ios - Potential Leak of an Object that is released before reuse and dealloc'd on exit -
using xcode analyzer, getting warning potential leak of object. warning perplexing , need explanation why getting error. here code in mediasources hold pointer object in question:
in .h file, pointer mediasources class created , given retain property:
@interface rootviewcontroller : uiviewcontroller <...> { ... mediasources *mediasources; ... } @property (nonatomic, retain) mediasources *mediasources;
in .m file (rootviewcontroller) method can called many times. consequently, release object on each entry , alloc new object. mediasources object performs background tasks, don't want release until know complete. if use autorelease on line class alloc'd in, crashes. :
-(void) getselectedmediasources { [self setmediasources: nil]; // release old stuff , nilify [self setmediasources: [[mediasources alloc] init]]; [self.mediasources checkformediasourceupdates]; }
also in .m file, mediasources synthesized , released in dealloc
@synthesize mediasources; ... - (void)dealloc { ... [mediasources release]; ... [super dealloc]; }
please explain why getting warning. don't see how there leak. dealloc should release last copy of object.
in response request code checkformediasourceupdates. going bit complicated, below essence:
(void) checkformediasourceupdates { nsstring *s = [nsstring stringwithformat:@"http://www.mywebsite.com/mediasources/%@/mediasources.plist", countrycode]; nsurl *url = [nsurl urlwithstring:s]; nsurlrequest *req = [nsurlrequest requestwithurl:url cachepolicy:nsurlrequestreloadignoringlocalandremotecachedata timeoutinterval:60.0]; mydownloader *d = [[mydownloader alloc] initwithrequest:req]; [self.connections addobject:d]; [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(checkformediasourceupdatesdownloadfinished:) name:@"connectionfinished" object:d]; [d.connection start]; [d release]; } -(void) checkformediasourceupdatesdownloadfinished: (nsnotification *) n { mydownloader *d = [n object]; nsdata *data = nil; if ([n userinfo]) { nslog(@"in checkformediasourceupdatesdownloadfinished: mydownloader returned error"); } else { data = [d receiveddata]; // data } }
the mydownloader class performs download of file specified in input nsurlrequest. after completing download, class generate nsnotification named "connectionfinished". user of class must register notification , handle cleanup operations of class. if download fails, class generate nsnotification, named "connectionfinished", addition of userinfo indicates error occured. again, user of class must register notification , handle cleanup operations of class.
per definition pass autoreleased object synthesized setter. setter retains object, following line wrong:
[self setmediasources: [[mediasources alloc] init]];
it should be:
[self setmediasources: [[[mediasources alloc] init] autorelease]];
also not need call setter nil
before. when setting different object via setter, old object gets released. synthesized setter looks like:
- (void) setmediasources:(mediasources *)mediasources { if (_mediasources != mediasources) { [_mediasources release]; _mediasources = [mediasources retain]; } }
the question is: why need allocate new mediasource
on every call getselectedmediasources
? crash expecting when deallocating autoreleased mediasource
? setting delegate object or registering nsnotificationcenter
? if so, not forget nil out delegate or remove notification center.
Comments
Post a Comment