2009-03-14 34 views
1

Ich habe ein iPhone-App, wo man Ansicht, Ansicht A, eine andere Ansicht in einer Tab-Leiste aktualisiert, Ansicht B, mit:Wann selbst zu verwenden?

// This works. 
- (void) reloadData 
{ 
    MyDB * db = _GET_DB_CLASS; 
    if(data != nil) // data is a property of type NSMutableArray 
     [data release]; 

    NSMutableArray * d = [db getDataQuery]; 
    data = s; // Don't release since we are not using the accessor. And retain count should be 1. 
} 

Wenn ich dies tue, ist es nicht funktioniert (zB I-Update B, wechseln Sie dann zu B, stürzen Sie ab, ich kann auch nichts Nützliches in den Logs sehen ...).

NSMutableArray * d = [db getDataQuery]; 
    self.data = s; // Doesn't work 
    [data release]; 

Ich habe keinen benutzerdefinierten Setter verwendet. Was ist los?

+0

Sollte das nicht "[s release]" statt "[data release]" sein? Und woher kommt dieses "s"? Sollte das "d" sein? –

+0

Dieser Code macht ohne die Klassendefinition wenig Sinn. Was ist s und wie ist es definiert? Wie ist MyDB '- (MSMutabalArray *)' implementiert usw. –

Antwort

0

Wenn Daten ist auf jeden Fall eine Eigenschaft, ohne zugrunde liegenden Wert des gleichen Namens, dann muss es von self wie in [[self data] release] oder [self.data release] zugegriffen werden. Wie bereits erwähnt, wenn die Eigenschaft auf automatisch beibehalten festgelegt ist, können Sie dasselbe erreichen, indem Sie die Eigenschaft auf einen neuen Wert setzen, z. B. . (Wie Sie in dem Code getan haben, den Sie notiert haben, funktioniert.)

0

Haben Sie Ihre Dateneigenschaft als "beibehalten" deklariert, im Gegensatz zu "zuweisen"? Sie sollten folgendes haben:

@property (behalten) NSMutableArray * Daten;

Wenn nicht, dann wird beim Zuweisen der Dateneigenschaft die Referenzzählung nicht erhöht. Ihre nachfolgende Version wird das Objekt freigeben und der nächste Verweis auf die Dateneigenschaft wird abstürzen.

Werfen Sie einen Blick auf die Apple docs for setter semantics für weitere Informationen zu behalten.

+0

Ja, ich habe. Es ist das typische @property (nonatomic, behalten) NSMutableArray * Daten; Zuerst dachte ich, dass es vielleicht Freigabe auf einen Nullwert sendet, aber ich bin sicher, dass sie das berücksichtigt haben und die generierten Setter und Getter werden mit Nils umgehen. – Megasaur

+0

RE: Nil: Senden von Release zu Nil tut nichts, wie alle Nachrichten zu Null. Ich denke nicht, dass das das Problem ist. –

+0

Ich weiß es nicht, Megasaur. Können Sie versuchen, mehr Code zu posten, beispielsweise was getDataQuery macht? Oder vielleicht, was für einen Unfall bekommst du und wo? Sind Sie sicher, dass getDataQuery einen beibehaltenen Wert zurückgibt? In der Regel erhalten Methoden mit dem Namen get * return autoreleased, nicht beibehaltene Werte. (Vielleicht möchten Sie den Namen ändern.) –

0

Wenn Sie nur eine Retain-Eigenschaft verwenden, sollten Sie im Allgemeinen immer self.data verwenden und den generierten Setter aufrufen.

It:

  1. fordert den alten Wert freigeben automatisch (Schecks für nil)
  2. fordert behalten auf den neuen Wert

Dann würde Ihr Code einfach sein:

self.data = s; 
[s release]; 

Zwei Dinge zu tun zu debuggen:

  1. Verwendung statische Analyse - Ich habe persönlich fand dieses Tool zu 100% genau zu sein mit behalten/Release Probleme: http://clang.llvm.org/StaticAnalysisUsage.html

  2. Folgen Sie den Anweisungen auf meinem Blog-Post auf Speicher-Debugging auf dem iPhone:

http://loufranco.com/blog/files/debugging-memory-iphone.html

+0

Guter Punkt. Ich bemerkte nicht einmal, dass er die Eigenschaft im ersten if-Block nicht verwendete. –

1

ich habe ganz vergessen darüber. Zu viel Arbeit. Ich bin mir also nicht sicher, wie genau das Problem war. Aber ich habe mir die RetainCounts im Debugger genauer angeschaut (bevor ich das ausprobierte, was Lou vorgeschlagen hatte).

Es ist ein Retain/Release-Problem. Ich schätze, die Regel muss mit Ihrer Verwendung übereinstimmen. Wie dem auch sei dies funktioniert:

 
- (void) reloadFridgeData 
{ 
    MyDB * db = _GET_DB_CLASS; 
    if(self.data != nil) 
    { 
     self.data = nil; 
    } 

    NSMutableArray * newData = [db getData]; 
    self.data = newData; 
    [newData release]; 
} 
Verwandte Themen