2010-11-19 23 views
9

Ich bin mir sicher, dass ich ein grundlegendes Verständnis von iOS-Speicherverwaltung vermisse und, trotz viel Lesen und Suchen, bekomme ich es immer noch nicht.iOS Singletons und Speicherverwaltung

Ich verwende ein Singleton in meiner App, das Informationen über den aktuell angemeldeten Benutzer enthält, Informationen, auf die von mehreren View-Controllern zugegriffen wird usw. Es verfügt über mehrere Ivars, die in der gesamten App abgerufen und eingerichtet werden. Sie sind deklariert und in der H-Datei begütert wie so:

NSString *myString; 

und bestehen beibehalten wie so:

@property (non atomic, retain) NSString *myString; 

und bei der Umsetzung synththesized.

ich und setzen ihre Werte in Methoden in der Singleton wie folgt aus:

myString = @"value"; 

und

methodLocalString = myString; 

In anderen Orten, die ich die Singleton umfassen - es nennen Current - I importiere es:

#import "CurrentUser.h"  

Außerhalb des Singleton bekomme ich und legen Sie es wie folgt aus:

[CurrentUser sharedCurrentUser].myString = @"Bob"; 

und

myOutsideString = [CurrentUser sharedCurrentUser].myString; 

das meiste Zeit funktioniert gut, mit den Werten beharrte in geeigneter Weise von einem bekommen oder auf eine andere Einstellung. Das Problem ist, dass manchmal, wenn ich sie auf diese Weise bekomme, ich feststelle, dass sie veröffentlicht wurden (Absturz der App), was mir NSZombieEnabled dankbar erklärt.

Was ich nicht verstehe, ist wie er passieren kann. Ich dachte, dass der Singleton nie veröffentlicht wurde, und dass deshalb beibehaltene Eigenschaften des Singletons nie veröffentlicht würden. Ich stelle fest, dass das Problem eher bei Nicht-Real-Objekt-Eigenschaften wie NSDate und Definitiv-Nicht-Objekt-Eigenschaften wie int und BOOL auftritt, die nicht beibehalten werden können, aber auch bei Objekteigenschaften.

Worüber bin ich hier unwissend? Und danke für deine Geduld.

+0

gute Frage. auf die Klärung warten. – harshalb

+1

Verwenden Sie nicht 'retain' mit' NSString' Eigenschaften. Verwende 'Kopieren'. –

+0

Danke für die nicht auf Kopie. Das sollte für alle Objekte sein, die NSCopying unterstützen, oder? –

Antwort

14

Ihr Problem ist:

ich und setzen ihre Werte in Methoden im Singleton wie folgt aus:

myString = @"value";

Wenn Sie zuweisen direkt an den iVar, statt Mit der Eigenschaftssyntax (self.myString = @"value") umgehen Sie die Methode der synthetisierten Setter, was bedeutet, dass die retain nie passiert.

Eigenschaften sind keine Magie. Sie sind nur ein bisschen syntaktischer Zucker für das "." Zugriff und die Fähigkeit, Getter/Setter-Methoden synthetisiert zu haben, um Ihnen die Mühe zu ersparen, Ihre eigenen zu schreiben.

self.myString = @"value"; 

ist nur eine Abkürzung für

[self setMyString:@"value"]; 

Das synthetisierte setMyString Methode wird wie etwas tun:

+0

Das macht * perfekt * Sinn, danke! –

0

Don't use singletons. Ihre aktuellen

if (myString != newValue) { 
    [myString release]; 
    myString = [newValue retain]; 
} 

(auf der @synthesize Annahme retain Option) Problem wird verursacht durch a Ein Fehler bei der Speicherverwaltung, aber das Singleton-Muster wird Ihnen auf lange Sicht nur Kopfschmerzen bereiten.

+1

Danke für den Vorschlag. Ich habe jetzt mehr als ein Dutzend Artikel über die Vor- und Nachteile gelesen und bin mit meiner Entscheidung zufrieden. –

+2

In der Regel verursachen Singletons in iOS-Apps große Kopfschmerzen. Aber Sie können sie benutzen, wenn Sie vorsichtig sind. Aber eine Sache, die Sie nie tun sollten, ist, UIKit-Elemente von Ihrem Singleton zu referenzieren. Ich habe die Verwendung von Singletons in vielen Projekten durchgesehen, und grundsätzlich kann jedes Mal, wenn ein Singleton Referenzen auf UIKit-Objekte oder andere Objekte enthält, die auf UIKit-Objekte verweisen, Sie sich am Ende in den Fuß schießen. Das Speicherlecks-Tool wird UIKit-Lecks nicht so erfassen, und Sie werden mit einer Unordnung von zirkulären Referenzen konfrontiert, die schwer zu beheben ist. – MoDJ