7

Kann der Speichermodifikator __weak in der Signatur einer Methodenimplementierung verwendet werden? Vor allem, wenn es nicht Teil der öffentlichen Signatur der Methode ist? Zum Beispiel:Verwenden von __weak zum Ändern des Speichers eines Parameters in der Implementierung

- (UIView *)tableView:(__weak UITableView *)tableView viewForHeaderInSection:(NSInteger)sectionIndex 
{ 
    UIView *view = [ABHeaderView view]; 
    view.actionBlock = ^{ 
     [tableView doSomething]; 
    } 
    // ... 
    return view; 
} 

Enthält diese korrekt tableView als schwacher Zeiger verwenden? Oder sollte ich wirklich etwas wie __weak *weakTableView = tableView; machen und innerhalb des Blocks weakTableView verwenden?

Ich bekomme keine Warnungen oder Fehler und der Clam Static Analyzer wirft keine Warnungen.

Antwort

1

Zählen Sie nicht auf Speichermodifikatoren oder -attribute, die dynamisch berücksichtigt werden sollen, wenn dynamischer Versand beteiligt ist und diese überschreibt (1).

Diese Methode wird in UIKit formell deklariert. Der Compiler kann bei der Verwendung von ARC Fehler bekommen, weil er beim Aufruf den Selektor mit der ursprünglichen Deklaration übereinstimmen kann. Das heißt, Ihre Deklaration ist für UIKit nicht sichtbar und UIKit behandelt sie als Standard/stark, wenn sie auch als ARC kompiliert wird. Dies kann passieren, wenn die Deklarationen nicht übereinstimmen oder wenn sie in der Übersetzung des Clients und des Aufrufers nicht sichtbar sind.

Parametertypen/Attribute sind weder Teil des Selektors, noch werden sie zum dynamischen Versand verwendet. ARC sollte hier stark annehmen, und dass der Aufrufer die Referenz enthält. Dieses spezielle Beispiel verursacht möglicherweise keinen Laufzeitfehler, aber es ist eine fragwürdige Praxis, von der ich vermute, dass Fehler gefunden wurden. Ich habe dies für Attribute in this answer nachgewiesen. Grundsätzlich ist es ein ähnliches Konzept.

Einfache Regel mit dynamischen Objc-Versand: Immer die Signatur der ursprünglichen Deklaration beim Redefinieren, Definieren und Überschreiben übereinstimmen. Die einzige Ausnahme, die man machen könnte, ist für C-kompatible Qualifizierer, die die Signatur nicht ändern würden (eine sehr häufige Praxis in ObjC-Programmen, die ich gesehen habe).

(1) technisch ist es keine Überschreibung, sondern eine Implementierung der Protokollmethode. Unabhängig davon sollte das Sig identisch sein.

0

__strong oder __weak Speichermodifikatoren sind Teil Ihrer internen Implementierung, soweit ich sehen kann. Sie beeinflussen nicht den Code, der vom Aufrufer der Methode generiert wird, daher denke ich, dass Sie jetzt sicher und sehr wahrscheinlich in der Zukunft sind.

Ich denke jedoch, es ist ein armer Stil, also scheint Ihr Vorschlag, den Verweis auf eine schwache Referenz zu kopieren, eine gute Lösung.