iPhone에서 예기치 않은 싱글 톤 클래스 행동, 내가 뭔가 잘못하고 있습니까?

StackOverflow https://stackoverflow.com/questions/1002364

  •  05-07-2019
  •  | 
  •  

문제

다음과 같이 싱글 톤 클래스를 구현하고 있습니다.

static Singleton* _singletonInstance;

@implementation Singleton

+(void)initialize
{ 
    _singletonInstance = [[Singleton alloc] init]; 
}

+(Singleton*)instance
{
    return(_singletonInstance);
}

누군가가 처음으로 인스턴스를 호출 할 때만 초기화 만 호출됩니다. 그런 다음 인스턴스 변수를 설정하기 위해 호출 할 수있는 메소드가 있습니다. 그래서 그것은 이렇게 보입니다.

_singleton = [Singleton instance];
[_singleton setupWithParams: blah];

이 싱글 톤의 인스턴스를 객체 안에서 얻으면 처음으로 잘 작동합니다. 그러나 싱글 톤의 인스턴스가 필요한 객체의 새 사본을 작성한 후 설정 함수를 호출하려고 할 때 액세스 오류가 잘못됩니다.

설정을 테스트하기 위해 설정 호출을하기 전에 인스턴스의 주소를 인쇄하고 동일한 주소를보고하지만 액세스 호출이 잘못된 오류 로그를 확인하면 완전히 다른 메모리 주소가 나열됩니다.

인스턴스에 대한이 포인터가 인쇄 할 때 왜 괜찮아 보이는지에 대한 아이디어가 있습니까? 그러나 전화를 걸 때 임의의 데이터를 가리키는 것처럼 보입니까?

도움이 되었습니까?

해결책

포인터 값은 예전 이었기 때문에 유효한 것처럼 보이지만 메모리가 무료 였기 때문에 임의의 데이터처럼 보이는 이유입니다.

당신은 당신과 하나의 참조를 얻었습니다 [[Singleton alloc] init] 위, 그러나 a release 실행 중일 수있는 다른 곳? 나는 당신의 코드가 호출 할 것이라고 확신합니다 instance, 그리고 release나중에 코드가 참조를 얻지 못했지만 나중에. 그리고 어쨌든 싱글 톤에는 필요하지 않습니다. 그냥 추측 ...

다른 팁

당신은 당신의 _singletoninstance를 어딘가에 거래하고 있습니까?

훨씬 더 복잡하지만 매우 안정적인 버전의 Singleton Template를 사용하고 있습니다 (설명과 함께 Brandon "Quazie"Kwaselow 블로그):

static SampleSingleton *sharedSampleSingletonDelegate = nil;

+ (SampleSingleton *)sharedInstance {
   @synchronized(self) {
      if (sharedSampleSingletonDelegate == nil) {
         [[self alloc] init]; // assignment not done here
      }
   }
   return sharedSampleSingletonDelegate;
}

+ (id)allocWithZone:(NSZone *)zone {
   @synchronized(self) {
      if (sharedSampleSingletonDelegate == nil) {
         sharedSampleSingletonDelegate = [super allocWithZone:zone];
         // assignment and return on first allocation
         return sharedSampleSingletonDelegate;
      }
   }
   // on subsequent allocation attempts return nil
   return nil;
 }

- (id)copyWithZone:(NSZone *)zone
{
   return self;
}

- (id)retain {
   return self;
}

- (unsigned)retainCount {
   return UINT_MAX;  // denotes an object that cannot be released
}

- (void)release {
   //do nothing
}

- (id)autorelease {
   return self;
}

Valerii의 코드는 싱글 톤을 구현하는 데 더 좋지만, 문제는 [Singleton 인스턴스]를 호출하는 코드가 실제로 소유권을 사용하지 않고 소유권이있는 것처럼 운영되고 나중에이를 공개하는 것입니다.

버그를 찾아서 읽으십시오 메모리 관리 규칙.

또한 Xcode에서 nszombieenabled를 활성화합니다 그리고 콘솔이 릴리스 된 후 객체를 메시지를 보내려고 할 때 콘솔이 표시됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top