Frage ARC-Rückgabeobjekt von Methode Best Practice (Speicherleckwarnung erhalten)


Ich habe ein Beispielprojekt in xcode 4.2 erstellt und festgestellt, dass das neue Projekt mit ARC eingerichtet wurde.

Ich habe eine Methode unten gezeigt. Zuvor hätte ich die Zelle in der Methode automatisch freigegeben und die Tabellenansicht des Aufrufers die Zelle beibehalten lassen. Mit ARC wäre eine Autoreleasing nicht möglich,

- (UITableViewCell*) getCellForIndex:(int)index {

    UITableViewCell *cell =         
        [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];

    if (index == 0)
        cell.textLabel.text = profileToUse.name;
    if (index == 1)
        cell.textLabel.text = profileToUse.sex;
    if (index == 2)
        cell.textLabel.text = profileToUse.city;
    return cell;
}

Wenn ich das Analyse-Tool auf dem obigen Code ausführe, heißt das, dass es ein mögliches Speicherleck des Objekts "Zelle" gibt.

Wie sollte das Obige mit ARC geschrieben werden, damit die Analysewarnung verschwindet? Was mache ich falsch?

Vielen Dank.


8
2018-01-08 18:49


Ursprung


Antworten:


Ihre Methode getCellForIndex: weist ein Objekt zu und gibt es zurück, auf diese Weise ähnelt es einem Straight alloc (In der Tat ist Ihr Code nur ein alloc mit etwas Initialisierung).

Da ARC die tatsächliche Implementierung einer Methode beim Aufruf nicht sieht, muss eine Annahme über den Besitz des zurückgegebenen Objekts getroffen werden, und diese Annahme ist, dass das Eigentum ist nicht übertragen. Beim Zusammenstellen Ihrer Implementierung bemerkt ARC, dass Ihr Code diese Annahme verletzt und Sie warnt.

Die Annahme kann durch Hinzufügen eines expliziten Attributs zu Ihrer Methode in beiden Fällen außer Kraft gesetzt werden @interface und @implementation:

- (UITableViewCell*) getCellForIndex:(int)index __attribute((ns_returns_retained))

ARC wird nun wissen, dass der Objektbesitz übertragen wird. Methoden in der alloc, new usw. Familien haben dieses Attribut automatisch hinzugefügt. Wie andere Antworten vorschlagen, sollten Sie besser Ihre Methode umbenennen, newCellForIndex: könnte hier als angemessen sein new wird für eine Kombination von verwendet alloc und init was ist Ihre Methode.

BTW: Ändern Sie Ihre zweite und dritte ifist es else ifDas würde deinen Algorithmus klarer machen (und etwas schneller, aber das ist nicht der Grund dafür).

Frage im Kommentar:

ARC führt neue Attribute usw. ein, verwendet aber auch Inferenz und Standardwerte, so dass Sie, wenn Sie normalen Cocoa-Konventionen folgen, diese nicht zu oft benötigen sollten - natürlich YMMV ... Zusätzlich zu Apples Dokumentation finden Sie eine Beschreibung Hier.


4
2018-01-08 20:30



Versuchen Sie, die Methode in -cellForIndex umzubenennen :, "get" - vordefinierte Methoden haben ein anderes implizites Verhalten in Cocoa.

(Vielleicht auch -cellAtIndex: für Konsistenz mit NSArray, etc ...)


5
2018-01-08 19:08