2012-02-14 29 views
12

(Xcode 4.2, iOS 5, ARC)portati Nucleo Fondazione Proprietà

ho alcune proprietà di Core Foundation (/ Grafica) oggetti che dovrebbero prendere la proprietà dei loro oggetti. Ora, in questi Apple docs ho trovato questo:

In OS X v10.6 e successive, è possibile utilizzare la parola chiave __attribute__ per specificare che una proprietà Nucleo Fondazione dovrebbe essere trattato come un oggetto Objective-C per la gestione della memoria: @property(retain) __attribute__((NSObject)) CFDictionaryRef myDictionary;

purtroppo non ho potuto trovare alcuna elaborazione su questo. Sto usando questo:

@property (nonatomic, strong) __attribute__((NSObject)) CGImageRef loupeImage;

E sembra per lavorare nel modo che ci si aspetterebbe. Mantiene l'oggetto sull'impostazione della proprietà e lo rilascia quando imposto la proprietà su zero.

Ora la mia domanda è: devo ancora impostare esplicitamente tali proprietà su zero nel mio dealloc?

risposta

15

Modifica: Il mio post precedente non era corretto. __attribute__((NSObject)) sulla proprietà fa sì che mantenga/rilasci la proprietà quando si utilizzano i metodi di accesso proprietà. Non influisce sull'accesso a ivar e, in particolare, non annulla (o rilascia) la proprietà in dealloc. Quindi sì, nel tuo dealloc devi dire self.loupeImage = nil; o devi dire [_loupeImage release].


Original post:

Se il compilatore accetta la parola chiave strong, quindi sta andando a trattare in modo corretto, conservando e rilasciando come previsto, e nilling automaticamente in ARC. L'intera idea di __attribute__((NSObject)) dice al compilatore di trattare questo oggetto esattamente come se fosse un oggetto obj-c, e così è quello che fa.

Quindi no, non dovresti esplicitamente annullarli in dealloc. Otterrai automaticamente il comportamento ARC predefinito di nilling/release.

+0

Mi sono reso conto che potevo anche controllare questo con un piccolo pezzo di codice ed è davvero come dici tu, li zero automaticamente. –

+0

@Patrick Mi chiedo se è possibile rilasciare il codice di test (su Github Snippet o qualcosa del genere). – adib

+0

@adib Questo codice attualmente funziona più, si veda [SO 9684972] (http://stackoverflow.com/questions/9274397) –

1

Ora la mia domanda è: devo ancora impostare esplicitamente le proprietà su zero nel mio dealloc?

, si fa, con la dichiarazione che avete mostrato.

Nel Property declarations section della specifica ARC, si dice:

Applicando __attribute__((NSObject)) a una proprietà non di conservazione di tipo puntatore oggetto ha lo stesso comportamento che fa al di fuori di ARC: si richiede il tipo di proprietà per essere una sorta di puntatore e consente l'uso di modificatori diverso da assign.Questi modificatori influenzano solo il getter e il setter sintetizzato ; gli accessi diretti a ivar (anche se sintetizzato) hanno ancora semantica primitiva, e il valore nel ivar non verrà rilasciato automaticamente durante la deallocazione.

(enfasi sulla parte finale aggiunto da me)

In altre parole, l'applicazione di __attribute__((NSObject)) e strong su una proprietà di tipo core Fondazione rende i getter e setter funzionano correttamente, ma non farà ARC gestire il variabile di istanza sottostante (poiché il tipo della variabile di istanza sarà ancora il tipo di Core Foundation) e pertanto ARC non rilascerà la variabile di istanza su dealloc se non è nullo. Con tale dichiarazione di proprietà, sarà necessario annullarlo in dealloc o causare una perdita.

Tuttavia, esiste un modo per rendere ARC gestire la variabile stessa. Poiché la variabile ha un tipo di base Core, puoi renderlo un tipo gestito da ARC inserendolo in un typedef con __attribute__((NSObject)).

La Retainable object pointers section della specifica ARC dice:

ci sono tre tipi di tipi di puntatore oggetto retainable:

  • puntatori di blocco (formata applicando il cursore (^) dichiaratore sigillo ad una tipo di funzione)
  • Objective-C puntatori di oggetti (id, Class, NSFoo*, ecc.)
  • typedef contrassegnati con __attribute__((NSObject))

(enfasi sulla ultimo elemento aggiunto da me)

Quindi, se si effettua una typedef come questo:

typedef __attribute__((NSObject)) CGImageRef MyImageRef; 

e dichiarare la vostra proprietà così:

@property (nonatomic, strong) MyImageRef loupeImage; 

la variabile sottostante sarà gestita da ARC (poiché la variabile sottostante avrà il tipo typedef 'd, che è un tipo gestito da ARC) e non sarà necessario annullarlo in dealloc.

Problemi correlati