iOS - 엄격한 단일 설계 모드

3812 단어

단일 모드 소개

  • 단일 모델은 시스템 중의 한 종류가 하나의 대상 실례만 있다는 것을 확보하는 것이다.어떤 방법으로 몇 번을 만들든지 얻은 대상은 같은 대상이다.

  • 단일 모드의 응용 장면

  • iOS 개발 과정에서 우리는 이미 많은 단일 모델의 모습을 만났다.
  • [UIApplication shared Application], [NSUser Defaults standard User Defaults], [NSNotification Center default Center] 등등.
  • 음악 플레이어에서 음악을 재생하는 플레이어 대상, 한 앱에서 저장하고 수시로 편리하게 얻을 수 있는 사용자 정보 대상 등.


  • 단일 모드의 관건

  • 대상은 한 번만 창설
  • 글로벌 액세스
  • 프로그램이 끝날 때까지 풀리지 않음
  • 단례 모델의 분석과 실현

  • 대상은 한 번만 만듭니다. iOS에서 우리는 하나의 대상을 만듭니다. 일반적으로:alloc init나 new를 사용합니다. 그 중에서 new 방법 내부도 실제적으로alloc init를 통해 만듭니다. 그래서 우리는 alloc init에 주의를 기울입니다.우선 alloc 방법은 대상에게 메모리 공간을 분배하고 init 방법은 이 대상을 초기화하는 것이다. 따라서 대상을 제어하는 관건은 alloc 방법에 있다. 또한alloc는 기본적으로 allocWithZone 방법을 호출하기 때문에 우리는 allocWithZone 방법을 다시 써서 대상을 제어해야 한다.
  • id instance; //  , , 
    + (instancetype)allocWithZone:(struct _NSZone *)zone {
        //  if , , 
        if (instance == nil) {
            //  : 
            @synchronized(self) {
                if (instance == nil) {
                    instance = [super allocWithZone:zone]; //  super , 
                }
            }
            //  :GCD 
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                instance = [super allocWithZone:zone]; //  super , 
            });
        }
        return instance;
    }
    
  • 전역 접근 가능: 단례 모드는 단례 대상을 얻는 클래스를 제공해야 한다. 예를 들어
    Tools *tools = [Tools sharedTools];
    UserTool *userTool = [UserTool defaultUserTool];
    
    실현은 다음과 같다.
    //    : shared +     default +  
    + (instancetype)sharedTools {
        if (instance == nil) {
            instance = [self alloc] init]; //  allocWithZone 
        }
        return instance;
    }
    
  • 은 프로그램이 끝날 때까지 풀리지 않습니다. 첫 번째 관건에서 전역 변수id instance;를 정의하여 우리가 만든 단일 대상을 저장합니다. 그러나 다른 파일에서 extern 키워드를 사용하면 이 대상을 얻을 수 있고 이 대상을 소각할 수 있습니다. 예를 들어
    extern id instance;
    instance = nil;
    
    이렇게 해서다음에 단일 대상을 가져올 때 nil로 다시 만들 대상을 발견합니다. 즉 2차 창설 대상입니다. 또한 단일 모드가 아닙니다. 단일 대상의 소각을 방지하기 위해서 우리는 static 수식을 사용하여 단일 대상의 변수를 저장해야 합니다. 변수의 역할 영역을 이 파일로 사용할 수 있도록 제한해야 합니다. 그러면 다른 파일 (다른 클래스) 은 이 대상을 가져올 수 없고 단일 대상은 방출되지 않습니다.id instance;static id instance;
  • 로 바꾸다

    엄격한 단일 패턴

  • 창설 대상은 alloc init와 new를 제외하고는copy와mutable Copy를 통해 창설할 수 있다. 엄밀하게 보기 위해서 우리는 이 두 가지 방법의 창설 과정을 통제해야 한다. 즉,copy WithZone과mutable Copy WithZone 방법을 다시 써야 한다. 이 두 가지 방법을 다시 쓰기 위해서는 각각 NSCopying과 NSMutable Copying 프로토콜을 준수해야 한다.이 두 가지 방법은 대상 방법이기 때문에 이 두 가지 방법을 사용하여 새로운 대상을 만들려면 단례 대상으로만 이 방법을 호출할 수 있다. 즉, 단례 대상이 이미 만들어졌기 때문에 우리는 우리가 저장한 단례 대상을 되돌려주면 된다. 코드는 다음과 같다.
    - (id)copyWithZone:(NSZone *)zone {
        return instance;
    }
    - (id)mutableCopyWithZone:(NSZone *)zone {
        return instance;
    }
    
  • 이렇게 엄격한 단일 예제 디자인 모델이 완성되었으니 아래에 전체 코드를 첨부합니다.

    #import "Tools.h"
    
    @implementation Tools
    
    static id instance;
    + (instancetype)sharedTools {
        if (instance == nil) {
            instance = [[self alloc] init];
        }
        return instance;
    }
    + (instancetype)allocWithZone:(struct _NSZone *)zone {
        //  if , , 
        if (instance == nil) {
            //  : 
            @synchronized(self) {
                if (instance == nil) {
                    instance = [super allocWithZone:zone]; //  super , 
                }
            }
            //  :GCD 
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                instance = [super allocWithZone:zone]; //  super , 
            });        
        }
        return instance;
    }
    //  NSCopying  
    - (id)copyWithZone:(NSZone *)zone {
        return instance;
    }
    //  NSMutableCopying 
    - (id)mutableCopyWithZone:(NSZone *)zone {
        return instance;
    }
    @end
    

    참고 문장


    http://lib.csdn.net/article/ios/35938

    좋은 웹페이지 즐겨찾기