Clang: Was ist „Methode gibt ein Objective-C-Objekt mit einem 0 behalten count“ versucht, mir zu sagen?

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

Frage

Ausführen einer statischen Analyse mit Klappern in beiden XCode 3.2 und Nikita Zhuk der Analysis Tool Ich habe kommen oft über dieses Paar Warnungen:

  

Methode gibt ein Objective-C-Objekt mit einer 0 Beibehaltungszähler (nicht besitzt Referenz)

     

Falsche Abnahme der Referenzzähler eines Objekt wird an dieser Stelle nicht vom Anrufer im Besitz

Ein Beispiel für Code, der diese Warnung auslösen kann:

UIButton* button = [[UIButton buttonWithType:UIButtonTypeCustom] initWithFrame: CGRectMake(x, y, width, height)];
return button;

ich davon aus, dass auf diese Weise erstellt Buttons Autoreleased sind, genau wie jede andere NSObject mit einer Convenience-Factory-Methode erstellt. Also habe ich es zurückbringen, und der Anrufer kann entscheiden, ob sie behalten oder nicht. Was ist das Problem?

Bin ich verpflichtet zu halten und das Objekt Autorelease, bevor er zurückkehrt? Und vor allem kann, was diese Warnung vor immer die Ursache von scary Release-bedingten Abstürzen sein warnt?

Ich weiß jetzt, dass dies nur scheint mit UIButtons auftreten. Ist es aufgrund es eine Klasse Cluster zu sein?

EDIT: Die snipped unten zeigt einen minimalen Fall, in dem Klirren diese Warnungen ausgibt (die Warnungen in fett). Beide Warnungen werden auf der Anweisung gekennzeichnet Erstellen Sie das Objekt (die buttonWithType: Meldung).

-(UIButton*) ztupidTezt:(UIImage*) img
{
  UIButton* bt = [[UIButton buttonWithType:UIButtonTypeCustom]initWithFrame:

1 Methode gibt ein Objective-C-Objekt mit einer 0 Beibehaltungszähler (nicht besitzt Referenz)

2 Falsche Abnahme der Referenzzähler eines Objekt wird an dieser Stelle nicht vom Anrufer im Besitz

    CGRectMake(0.0f, 0.0f, img.size.width, img.size.height)];
    bt setImage:img forState:UIControlStateNormal];
    return bt;
}
War es hilfreich?

Lösung

Die Ursache ist wahrscheinlich die Verwendung von sowohl eine buttonWithType: und initWithFrame: Nachricht sendet. init* Methoden führen Aufgaben, die nur einmal für ein bestimmtes Objekt durchgeführt werden sollte. Klassenmethoden, die Objekte auch sie schaffen initialisieren. Das Ergebnis des Codes wird die Initialisierung wiederholt. Stattdessen die buttonWithType Nachricht senden, dann ordnen Sie die frame Eigenschaft.

Andere Tipps

Nun .... das Code macht keinen Sinn.

buttonWithType: gibt eine Instanz eines UIButton, die bereits initialisiert wird. Sie sollten nicht -initWithFrame: darauf anrufen.

Anruf setFrame:.

Der schlechte Code ist verwirrend den Analysator.

Zweitens, warum mit einem Dritten Werkzeug Mühe, die Analyse zu tun. Wenn Sie Xcode 3.2 auf Snow Leopard verwenden (sollten Sie sein - es ist eine wesentlich bessere Version von Xcode als die letzte Version auf Leopard ist), können Sie einfach „bauen und analysieren“. Alle Analyseergebnisse Inline ganz gut mit Ihrem Code präsentiert wird.

Gibt den Namen der Methode, die diesen Code in sich haben „neu“ als Präfix hat? Der Clang Static Analyzer folgt Standard-Cocoa-Namenskonventionen und geht davon aus, dass ein -newSomething Methode eine Instanz mit einer Beibehaltungszähler von 1 zurück, wenn es ein Autoreleased Objekt zu sehen, aus einem solchen Verfahren zurückgeführt wird, könnte es die Warnung präsentieren Sie sehen.

Alt, alt, Frage. Ich habe das gleiche Problem. Ich denke, dass die vorhandenen Antworten erfolgreich erklärt, warum der Code falsch ist, und warum der Analysator sagt „+0 behalten count“. Allerdings sieht es nicht wie jemand erklärt, warum der Analysator sagt der Code dekrementiert die Zählung beibehalten. Ich glaube, ich herausgefunden, warum. Es ist, weil, wie init Methoden erlaubt ein anderes Objekt zurück, als Sie die Nachricht gesendet haben. Sie würden lösen das ursprüngliche Objekt, Alloc ein neues, und gibt es zurück. Der Analysator ist unter der Annahme, dass jede Methode init so etwas tun könnte, obwohl die init-Methode in diesem Beispiel auch nicht.

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