6

Ich habe einen Selektor mit Namen auf einer Klasse (keine Instanz) und verwenden den Rückgabewert auszuführen:"performSelector kann ein Leck verursachen" Alternative, wenn es leck wird?

id obj = [objClass performSelector:NSSelectorFromString(methodName) withObject:p1]; 

Der Selektor erstellt eine neue Instanz der Klasse. Ich muss die zurückgegebene Instanz verwenden. Offensichtlich bekomme ich die üblichen performSelector kann ein Leck verursachen, weil sein Selektor unbekannt ist Warnung, da dieses Projekt mit ARC kompiliert wird.

Wenn ich das richtig verstanden (from the answers here und andere), in diesem Fall die perform wird ein Leck verursachen (mich korrigiert, wenn ich falsch bin, dann könnte ich nur die Warnung abzuschalten und mit ihm getan werden). Die Wähler implementiert sind wie folgt:

+ (id) objectWithFile:(NSString*)p1 
{ 
    return [NSKeyedUnarchiver unarchiveObjectWithFile:p1]; 
} 

Was sind meine Optionen, wenn ich Wähler aus Zeichenfolge verwenden, und die Auswahl erzeugt und gibt eine neue Instanz des Objekts?

Ich betrachtete NSInvocation, aber seine getReturnValue Methode erfordert, dass ich meinen eigenen reservierten Puffer zur Verfügung stelle, in dem der Rückgabewert gespeichert wird. Ich bin mir nicht sicher, ob dies sogar mit ARC und Klassenmethoden funktioniert, oder ob ich einfach __bridge_transfer den malloced Rückgabewertpuffer zu id umwandeln muss und das ist alles, was es ist.

+0

Ich verstehe noch nicht, warum Sie in Ihrem Fall ein Leck haben würden. 'objectWithFile:' gibt ein automatisch freigegebenes Objekt zurück, da es sich nicht um eine Methode "alloc/copy/new" handelt. –

+0

Ich bin mir nicht sicher, ob ich das richtig verstehe. Angenommen, ich gebe [Objekt neu] anstelle des nicht archivierten Objekts zurück, das ebenfalls ein Objekt zur automatischen Freigabe zurückgibt, das aber dann ausläuft? Oder würde das Leck ** nur ** auftreten, wenn der ausgeführte Selektor selbst Alloc, New oder Copy aufruft? – LearnCocos2D

Antwort

5

objectWithFile: ist keine Methode der „alloc, kopiert, init, mutableCopy und neue Familie“ und deshalb ist eine „nicht zurückgehaltener Rückgabewert“ Methode im Sinne der "Clang/ARC documentation":

Eine Methode oder Funktion, die einen beibehaltenen Objekttyp zurückgibt, aber einen zurückbehaltenen Wert nicht zurückgibt, muss sicherstellen, dass das Objekt über die Rückkehrgrenze hinweg immer noch gültig ist .
...
Im schlimmsten Fall kann dies eine automatische Freigabe sein, aber Anrufer müssen nicht davon ausgehen, dass der Wert tatsächlich im Autorelease-Pool ist.

Also egal, was Sie innerhalb der Methode tun, muss der Aufrufer das zurückgegebene Objekt nicht freigeben.

Daher glaube ich nicht, dass Sie einen Speicherverlust in Ihrem Code haben.

+0

Danke, das macht Sinn. Bestätigt auch meine Beobachtung, da die zurückgegebenen Objekte freigegeben werden, wenn sie nicht mit einem starken Verweis festgehalten werden. – LearnCocos2D