iOS - 단일 디자인 모드

3178 단어

단일 응용 장소


iOS의 생명 주기 내에 때때로 우리는 특정한 종류의 실례만 필요로 한다.
예를 들어 UIApplication, UIACcelerometer, NSUserDefaults, NSNotificationCenter, NSFileManager, NSBundle 등은 모두 일례류의 전형적인 대표이다.

단일 예제 클래스를 만드는 방법

  • 정적 객체 만들기
  • 정적 방법 제공
  • 다시 쓰는 alloc 방법
  • 코드 데모


    먼저 NSObject에서 상속된 Singleton을 만듭니다.
    정적 글로벌 변수를 추가하려면 다음과 같이 하십시오.
    static Singleton *_singleton = nil;
    

    정적 방법을 만듭니다.
    +(Singleton *)shareSingleton
    {
        //         ,           ,       ,         ,     ,            。                 
        //@synchronized:           ,         ,      。
        @synchronized(self)
        {
            if (_singleton == nil)
            {
                _singleton = [[self alloc]init];
            }
            return _singleton;
        }
    }
    

    우리가 단일 클래스를 만드는 목적은 전역적으로 하나의 대상만 만들 수 있는 것이다. 그러나 위의 방법으로 문제를 만들면 사용자가shareSingleton으로 대상을 만들지 않고alloc 방법으로 대상을 만들면 하나의 대상 실례가 생성된다. 이것은 우리 프로젝트에서 하나의 충돌만 생성하는 것이다. 그러면 우리는 어떻게 해야 합니까?
    첫 번째 반응은 alloc 방법을 다시 써야 한다는 것이다. 실제로 우리는 alloc 방법을 다시 쓸 필요가 없다.(아래 설명서)
    우선 alloc 방법을 다시 쓰겠습니다.
    +(id)alloc
    {
         @synchronized(self)
        {
            if (_singleton == nil)
            {
                _singleton = [super alloc];
            }
            return _singleton;
        }
    }
    

    사용자가 alloc 방법으로 대상을 만들 수 있는 이상, 사용자가 allocWithZone으로 대상을 만들 수 있습니까?
    AllocWithZone을 다시 쓰는 방법도 필요합니다.
    +(id)allocWithZone:(struct _NSZone *)zone
    {
        @synchronized(self)
        {
            if (_singleton == nil)
            {
                _singleton = [super allocWithZone:zone];
            }
            return _singleton;
        }
    }
    

    alloc를 다시 쓰는 것과 allocWithZone을 다시 쓰는 것은 어떤 차이가 있습니까?
    allocWithZone은 비교적 전면적인 방법으로 alloc 방법 내부에서 allocWithZone이라는 방법을 사용한다.
    allocWithZone에서는 alloc이 호출되지 않습니다.
    그래서 alloc를 다시 쓸 필요가 없고, 직접 allocWithZone을 다시 쓰면 된다.
    기본 코드는 다음과 같습니다.
    #import "Singleton.h"
    static Singleton *_singleton = nil;
    @implementation Singleton
    +(Singleton *)shareSingleton
    {
       
        @synchronized(self)
        {
            if (_singleton == nil)
            {
                _singleton = [[self alloc]init];
            }
            return _singleton;
        }
    }
    +(id)allocWithZone:(struct _NSZone *)zone
    {
        @synchronized(self)
        {
            if (_singleton == nil)
            {
                _singleton = [super allocWithZone:zone];
            }
            return _singleton;
        }
    }
    

    상술한 코드는 ARC에서만 정확하게 사용할 수 있다. 만약에 실제 MRC에retain,copy,release,autorelease가 있다면 이런 방법들은 인용 계수를 변화시킬 수 있다. 우리는 모두 이런 방법에 대해 다시 써야 한다.
    -(id)retain
    {
        return _singleton;
    }
    -(void)release
    {
        
    }
    -(id)autorelease
    {
        return _singleton;
    }
    -(id)copy
    {
        return _singleton;
    }
    -(NSUInteger)retainCount
    {
        return 1;
    }
    

    좋은 웹페이지 즐겨찾기