7

È valido utilizzare il modificatore di memorizzazione __weak nella firma dell'implementazione di un metodo? Soprattutto se non fa parte della firma pubblica del metodo? Per esempio:Utilizzare __weak per modificare l'archiviazione di un parametro nell'implementazione

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

Questo usare correttamente tableView come puntatore debole? O dovrei davvero fare qualcosa come __weak *weakTableView = tableView; e usare weakTableView all'interno del blocco?

Non ricevo alcun avviso o errore e l'analizzatore statico di clang non genera avvisi.

risposta

1

Non contare su modificatori di memorizzazione o attributi da onorare 'dinamicamente' quando la spedizione dinamica è coinvolta e sovrascritta (1).

Questo metodo è formalmente dichiarato in UIKit. Il compilatore può sbagliare quando si usa ARC perché potrebbe corrispondere al selettore alla dichiarazione originale quando viene chiamato. Cioè, la tua dichiarazione non è visibile a UIKit, e Uikit lo tratterà come default/forte se è compilato come ARC. Ciò potrebbe accadere se le dichiarazioni non corrispondono, o anche se non sono visibili nella traduzione del client + del chiamante.

I tipi di parametri/attributi non fanno parte del selettore, né vengono applicati alla spedizione dinamicamente. ARC dovrebbe assumere forza qui e che il chiamante chiamante detenga il riferimento. Questo esempio specifico non può causare un errore di runtime, ma è una pratica discutibile che presumo che si possano trovare errori. Ho provato questo per gli attributi in this answer. Fondamentalmente, è un concetto simile.

Regola semplice con invio objc dinamico: corrisponde sempre alla firma della dichiarazione originale quando si ridichiano, si definiscono e si sovrascrivono. L'unica eccezione che si potrebbe fare è per i qualificatori compatibili con C che non altererebbero la firma (molto pratica un nei programmi ObjC che ho visto).

(1) tecnicamente, non è un override, ma un'implementazione del metodo del protocollo. a prescindere, il sig dovrebbe essere identico.

0

__strong o __weak I modificatori di archiviazione fanno parte dell'implementazione interna, per quanto posso vedere. Non influenzano il codice generato dal chiamante del metodo, quindi penso che tu sia al sicuro ora e molto probabilmente in futuro.

Penso che sia di pessimo stile, quindi, il tuo suggerimento di copiare il riferimento a un riferimento debole sembra una buona soluzione.

Problemi correlati