2011-11-03 17 views
18

Ho convertito la mia app in ARC.- [Non A Type retain]: messaggio inviato all'istanza deallated

Prima ho avuto la seguente riga di codice:

NSArray *colors = [NSArray arrayWithObjects:startColor, endColor, nil]; 

Dal momento che la conversione implicita di un non-Objective-C di tipo puntatore a 'id' non è consentita con l'arco, ho riscritto la linea come questa:

NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil]; 

Tutto funziona bene sul simulatore, ma sul dispositivo l'applicazione si blocca sulla linea menzionata con il messaggio di errore:

-[Not A Type retain]: message sent to deallocated instance 

Qualche idea su come risolverlo?

+0

quali tipi sono le variabili? il codice circostante andrebbe bene per determinare se hai bisogno di '__bridge',' __bridge_retained' o '__bridge_transfer' –

+0

I tipi delle variabili sono CGColorRef. Non sono sicuro di cosa intenda per "codice circostante", ma ho provato tutte e 3 le versioni di "__bridge", ma il problema persiste. – Gytis

+0

come si crea CGColorRef? lo rilasci? .. –

risposta

30

Questo cast a ponte potrebbe non funzionare, come il hatfinch descrive in his answer here, poiché CGColorRef restituito da -CGColor potrebbe non rimanere in attesa dopo l'ultimo riferimento a UIColor che lo genera. Ho pensato che si trattasse di un bug, basato sulla discussione in this Apple developer forum thread, ma si trattava di una lettura errata di come gestire la durata di questi CGColorRefs.

Un modo per farlo funzionare è utilizzare il bridging integrato fornito dal metodo -CGColor su UIColor. Invece di salvare la vostra CGColor a una variabile temporanea come si fa sopra, si dovrebbe essere in grado di usare qualcosa come il seguente:

NSArray *colors = [NSArray arrayWithObjects:(id)[color1 CGColor], 
              (id)[color2 CGColor], nil]; 

con color1 e color2 essere casi UIColor.

Il bridging è gestito per voi dal metodo -CGColor, in base alla sezione "Il metodo di compilazione di CF oggetti restituiti da metodi di cacao" del Transitioning to ARC Release Notes. La documentazione attualmente manca il cast per l'id che ho sopra, che è necessario per ottenere questo per compilare.

L'ho provato e sembra funzionare nel mio caso, facendo corrispondere ciò che Ben riporta nel thread Forum degli sviluppatori sopraindicato.

In aggiunta a quanto sopra, è possibile mantenere e rilasciare in modo esplicito i CGColorRef restituiti dal metodo -CGColor e collegarli attraverso il proprio NSArray, sempre come hatfinch mostra here.

+0

Questo è corretto. Avevo risolto questo problema personalmente nello stesso modo, ma non potevo rispondere alla mia domanda a causa della restrizione di StackOverflow (rispondendo alla tua stessa domanda diverse ore dopo averla postata). Grazie! – Gytis

+1

Hai salvato il mio giorno. Mi sono strappato i capelli per ore sopra questo. –

+1

Grazie a te, non ho dovuto strapparmi i capelli come Jason! – NickDK

0

Modifica:
Se si utilizza la proprietà CGColor di UIColor, CGColor scompare nel momento in cui si fa riferimento l'ultima istanza UIColor. Per evitare questo, "ponte" i colori direttamente nella chiamata di funzione:

NSArray *colors = [NSArray arrayWithObjects:[uiStartColor CGColor], [uiEndColor CGColor], nil]; 

Questo metodo è descritto in Apple's documentation

originale:
Provate ad assegnare una variabile: id color = (__bridge_transfer id)CGColorCreate(...); e fare nient'altro con il ritorno diretto valore di CGColorCreate()

+0

Ho provato 'id color = (__bridge_transfer id) CGColorCreateCopy (...);' tuttavia non aiuta – Gytis

0

Grazie a @Brad per il suggerimento di -CGColor!

l'arresto anomalo dell'app nella riga seguente, che verrà richiamato da un oggetto NSInvocation.

CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); 

la soluzione alternativa è definire una proprietà di colore e utilizzarlo.

@property(strong, nonatomic) UIColor *backgroundColor; 
    ...... 
    self.backgroundColor = [UIColor whiteColor]; 
    ...... 
    CGContextSetFillColorWithColor(context, self.backgroundColor.CGColor); 
Problemi correlati