Frage

Ich bin die Implementierung einer Singleton-Klasse wie folgt:

static Singleton* _singletonInstance;

@implementation Singleton

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

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

initialisieren wird nur das erste Mal, wenn jemand ruft Instanz aufgerufen. Ich habe dann eine Methode, die ich anrufen kann einige Instanzvariablen einzurichten. So endet es nach oben wie folgt aussehen.

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

Wenn ich eine Instanz dieser Singleton innerhalb eines Objekts zu erhalten, funktioniert es das erste Mal in Ordnung; Aber nachdem ich eine neue Kopie des Objekts, das eine Instanz des Singleton muss, erhalte ich einen BAD ACCESS Fehler dealloc und erstellen, wenn ich versuche, die Setup-Funktion aufzurufen.

Just Dinge testen ich die Adresse der Instanz auszudrucken, bevor ich den Setup-Anruf und beiden Male berichten sie die gleiche Adresse, aber wenn ich das Fehlerprotokoll für BAD ACCESS Anruf überprüfen, listet es eine ganz andere Speicheradresse.

Hat jemand eine Idee, warum dieser Zeiger auf die Instanz in Ordnung zu suchen scheint, wenn ich es drucken, aber wenn ich einen Anruf zu machen, ist es scheinbar zeigt auf Zufallsdaten?

War es hilfreich?

Lösung

Der Zeigerwert sieht gültig, weil es früher, aber höchstwahrscheinlich der Speicher free'd wurde, weshalb, was es sieht aus wie zufällige Daten verweist.

Sie haben einen Hinweis mit Ihrem [[Singleton alloc] init] oben erworben, aber gibt es eine release woanders, dass die Ausführung werden könnte? Ich wette, Ihr Code instance anruft, und dann release-ing später, auch wenn der Code nie einen Verweis erworben. Und das sollte nicht sowieso für eine Singleton notwendig sein. Nur eine Vermutung ...

Andere Tipps

deallocing Sie Ihre _singletonInstance irgendwo?

Ich bin mit sehr viel komplexer, aber sehr stabile Version von Singleton-Vorlage (mit Beschreibung von Brandon "Quazie" Kwaselow Blog ):

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;
}

Valeriis Code ist besser für eine Singleton-Implementierung, aber das Problem ist fast sicher, dass der Code, der [Singleton Instanz] ruft arbeitet, als ob es das Eigentum hat, ohne den Besitz tatsächlich nehmen behalten verwenden und dann später freigibt es.

Schauen Sie dort für Ihre Fehler und lesen die Speicher Managment rel="nofollow Regeln .

Auch in Xcode, NSZombieEnabled ermöglichen und die Konsole wird Ihnen zeigen, wenn Sie versuchen Nachricht das Objekt nach seiner freigegeben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top