2012-01-24 2 views
5

Eventuali duplicati:
Why is object not dealloc'ed when using ARC + NSZombieEnabledproblema Strano ARC non rilasciando Ivar in UIView sottoclasse

Ho un problema molto strano che sto vedendo in questo momento in un progetto. In parole semplici, ho ViewA che possiede ViewB (strong proprietà). ViewA crea il suo ViewB nel suo inizializzatore. Entrambi gli oggetti sono sottoclassi di UIView.

Ho sovrascritto lo dealloc in entrambi e ho inserito una riga di registro e un punto di interruzione per vedere se vengono colpiti. Sembra che ViewA 's dealloc sia stato colpito ma non ViewB s. Tuttavia se inserisco un self.viewB = nil nel dealloc di ViewA, il numero è colpito.

Quindi, in pratica si tratta di qualcosa di simile:

@interface ViewA : UIView 
@property (nonatomic, strong) ViewB *viewB; 
@end 

@implementation ViewA 

- (id)initWithFrame:(CGRect)frame { 
    if (self = [super initWithFrame:frame]) { 
     self.viewB = [[ViewB alloc] initWithFrame:self.bounds]; 
     [self addSubview:self.viewB]; 
    } 
    return self; 
} 

- (void)dealloc { 
    //self.viewB = nil; ///< Toggling this commented/uncommented changes if ViewB's dealloc gets called. 
    NSLog(@"ViewA dealloc"); 
} 

@end 

Quello che non riesco a capire è perché nil-ing viewB fuori fa la differenza. Se qualcos'altro si aggrappa allo viewB allora non dovrebbe fare alcuna differenza se non lo faccio o no qui. E non dovrebbe fare la differenza per il numero di versioni che ARC aggiunge in entrambi.

Non riesco ancora a riprodurlo in un caso di test minimale, ma ci sto lavorando. E non posso pubblicare il codice reale che sto vedendo in sfortunatamente. Non vedo che questo sia un problema, però, perché è più il punto che nil-out non dovrebbe fare la differenza di cui sono confuso.

Qualcuno può vedere qualcosa che sto trascurando o dare consigli su dove cercare il debug di questo problema?

Aggiornamento:

ho trovato il problema. Sembra che sia solo un problema quando NSZombieEnabled è impostato su YES. Beh, è ​​completamente folle e dev'essere sicuramente un bug. Gli zombi non dovrebbero influenzare il modo in cui funziona per quanto ne so. Gli oggetti devono ancora passare attraverso il metodo dealloc. E per di più, è solo folle che funzioni se nullo fuori viewB in ViewA 's dealloc.

+0

Come argomento off, puoi renderlo 'weak' e dimenticare il problema:' [self addSubview: self.viewB] 'conserva' viewB' per te, quindi non verrebbe rilasciato prematuramente anche se tu mantenere un riferimento 'debole' ad esso. – dasblinkenlight

+0

A meno che non debba funzionare su iOS 4.3. –

+0

Precisamente. Voglio che funzioni su iOS 4.xe inoltre, I ** non dovrebbe farlo **. Non vedo perché nil-'viewB' in' dealloc' sta facendo la differenza. Mi sembra pazzesco. – mattjgalloway

risposta

4

Ho trovato che questo sembra essere un bug nell'implementazione iOS degli zombie. Si consideri il seguente codice:

#import <Foundation/Foundation.h> 

@interface ClassB : NSObject 
@end 

@implementation ClassB 
- (id)init { 
    if ((self = [super init])) { 
    } 
    return self; 
} 
- (void)dealloc { 
    NSLog(@"ClassB dealloc"); 
} 
@end 

@interface ClassA : NSObject 
@property (nonatomic, strong) ClassB *b; 
@end 

@implementation ClassA 
@synthesize b; 
- (id)init { 
    if ((self = [super init])) { 
     b = [[ClassB alloc] init]; 
    } 
    return self; 
} 
- (void)dealloc { 
    NSLog(@"ClassA dealloc"); 
} 
@end 

int main() { 
    ClassA *a = [[ClassA alloc] init]; 
    return 0; 
} 

Questo dovrebbe uscita:

ClassA dealloc 
ClassB dealloc 

Ma con NSZombieEnabled set per YES, emette:

ClassA dealloc 

Per quanto posso dire, questo è un bug. Sembra che accada solo con iOS (sia il simulatore che il dispositivo) e non accade quando è stato creato ed eseguito per Mac OS X. Ho archiviato un radar con Apple.

Modifica: Risultava che questo ha già avuto risposta qui - Why is object not dealloc'ed when using ARC + NSZombieEnabled. Sono riuscito a trovarlo dopo aver scoperto qual era il vero problema. A proposito, non ha niente a che fare con l'ARC.

+0

offtopic: no [super dealloc]; le chiamate? – CarlJ

+1

@meccan - No, dal momento che sto usando ARC. – mattjgalloway