ios - Why does this NSArray in an NSNotification block (apparently) never get released in an ARC environment? -


i have view controller that's subscribing notifications broadcast elsewhere. part of large object graph has cleanup needs done when children dealloc'd. dealloc never being called in 1 of children (arc environment), (if understand) means somewhere still retained, causing arc never dealloc when vc dismissed. i've traced offending code following 2 lines. first version causes vc , children never dealloc'd. in second version, things work fine , gets dealloc'd when vc dismissed.

my question why? arc can't understand why additional nsarray not released.

hopefully enough code. can post more if need be.

here's version leads vc (and children, etc) never being dealloc'd:

// subscribe notifications number of trackables has changed [[nsnotificationcenter defaultcenter] addobserverforname:kupdatednumberoftrackables object:nil queue:[nsoperationqueue mainqueue] usingblock:^(nsnotification *note) {     if ([note.object iskindofclass:[nsarray class]]) {         nsarray *activetrackablenames = note.object; // <-- offending line         [self trackableupdate:activetrackablenames]; // <-- offending line     } else {         nslog(@"observer error. object not nsarray");     } }]; 

but when following way, gets released when view unloaded, , dealloc called on child vcs:

// subscribe notifications number of trackables has changed [[nsnotificationcenter defaultcenter] addobserverforname:kupdatednumberoftrackables object:nil queue:[nsoperationqueue mainqueue] usingblock:^(nsnotification *note) {     if ([note.object iskindofclass:[nsarray class]]) {         [self trackableupdate:note.object]; // <-- seems work     } else {         nslog(@"observer error. object not nsarray");     } }]; 

a few other relevant methods in vc may(?) play role:

- (void)viewdiddisappear:(bool)animated {     [super viewdiddisappear:animated];     self.trackablesvisible_private = nil;     [[nsnotificationcenter defaultcenter] removeobserver:self]; }  #pragma mark - target handling -(void)trackableupdate:(nsarray *)trackablesarray {     nslog(@"trackable changed");     if (([trackablesarray count] > 0) && [self.delegate respondstoselector:@selector(foundvalidtargets:)]) {         [delegate foundvalidtargets:trackablesarray];     }     self.trackablesvisible_private = trackablesarray; } 

i don't understand what's going on here. please enlighten me?

thanks!

edit:

so noted in replies, part of issue retain cycle failing use weak self in block, apparently there's issue going on here because i'm using notification center. solution described here: dealloc not running when dismissing modal view block

my final working code follows:

in @interface

__weak id observer; 

in loadview

__weak thisviewcontroller *blockself = self; // avoids retain cycle observer = [[nsnotificationcenter defaultcenter] addobserverforname:kupdatednumberoftrackables object:nil queue:[nsoperationqueue mainqueue] usingblock:^(nsnotification *note) {     if ([note.object iskindofclass:[nsarray class]]) {         thisviewcontroller *strongself = blockself; // avoids retain cycle         nsarray *activetrackablenames = note.object;         [strongself trackableupdate:activetrackablenames];     } else {         nslog(@"observer error. object not nsarray");     } }]; 

and in viewwilldisappear

[[nsnotificationcenter defaultcenter] removeobserver:observer]; 

i don't yet understand why have save returned observer object, rather removing self, works.

you have retain cycle in block...here want

__weak myviewcontrollername *bself = self; // subscribe notifications number of trackables has changed [[nsnotificationcenter defaultcenter] addobserverforname:kupdatednumberoftrackables object:nil queue:[nsoperationqueue mainqueue] usingblock:^(nsnotification *note) {     if ([note.object iskindofclass:[nsarray class]]) {         **nsarray *activetrackablenames = note.object;         [bself trackableupdate:activetrackablenames];**     } else {         nslog(@"observer error. object not nsarray");     } }]; 

for more info on blocks , retain cycles, check out http://zearfoss.wordpress.com/2012/05/11/a-quick-gotcha-about-blocks/


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -