mikeash.com pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html commentshttp://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsmikeash.com Recent CommentsFri, 29 Mar 2024 06:43:44 GMTPyRSS2Gen-1.0.0http://blogs.law.harvard.edu/tech/rssSayeed Munawar Hussain - 2014-10-30 04:45:45http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsGreat post Mike. Thanks for creating Friday QA. Learned a lot here. 0476281b928bdd18e7b9cfc5e9e0e116Thu, 30 Oct 2014 04:45:45 GMTbob - 2012-12-14 23:55:37http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsAbout the NSTimer and retain cycles, this only applies to timers with repeat:YES, right? Because if it does not repeat, it will invalidate itself after firing, at which point it will release its target, so it is not a permanent retain cycle.5d321400a8e52109619cf6ce4c185cddFri, 14 Dec 2012 23:55:37 GMTOmar - 2012-11-02 19:34:38http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsI understand, thanks.98bc1f7c8ff331276a15cf9accdf1954Fri, 02 Nov 2012 19:34:38 GMTmikeash - 2012-11-02 15:03:32http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsNSThread will retain the target for as long as the thread is alive. If you're terminating the thread before your object is supposed to be deallocated, you're fine. If you're telling the thread to exit in -dealloc, then you'll never get there. <br /> <br />All Cocoa APIs need a periodic autorelease pool drain to clean up their stuff. If you're running your own long-lived thread, then you need an autorelease pool in your thread's top-level loop.b86aa73fec473481747699f4ba1cb284Fri, 02 Nov 2012 15:03:32 GMTOmar - 2012-10-29 04:41:14http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsWhat about NSThread? <br />For example, if I have, in a viewDidLoad: <br />myThread = [NSThread detachNewThreadSelector: @selector(go) toTarge:self withObject:nil]; <br /> <br />And then I have <br />- (void) go <br />{ <br />&nbsp;&nbsp;//do something <br />} <br /> <br />There is no cycle here, correct? When the go function ends, so does the Thread... or not? <br /> <br />What if the go function were something like this: <br /> <br />- (void) go <br />{ <br />&nbsp;&nbsp;while (![NSThread isCancelled]) <br />&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;//alloc something <br />&nbsp;&nbsp;&nbsp;&nbsp;NSData *d = [NSData dataWithContentsOfFile: @"somefilepath"]; <br />&nbsp;&nbsp;&nbsp;&nbsp;[NSThread sleepForTimeInterval:1]; <br />&nbsp;&nbsp;} <br />} <br /> <br />I found out, in this case, that "d" is never deallocated, until the thread exits. <br />It seems that an @autoreleasepool{} is needed around the NSData allocation, for it to be properly released after each cycle. Is that correct? <br /> <br />But still, if I have for example: <br /> <br />- (IBAction) goBack <br />{ <br />&nbsp;&nbsp;[myThread cancel]; <br />&nbsp;&nbsp;myThread = nil; <br />&nbsp;&nbsp;[self.navigationController popViewControllerAnimated:YES]; <br />} <br /> <br />This will still clear the thread, and the viewController itself, and all the NSData that were allocated, right? <br /> <br />Anything else I should be aware when doing things like these? <br /> <br />Thanks a lot for your very informative posts. <br />f270dcae9104d55fe0be487bf4f36845Mon, 29 Oct 2012 04:41:14 GMTmikeash - 2010-05-29 23:04:02http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsUsing a setter to set to nil is just a convenient way to release the variable. For more information on this technique and the pros and cons of it, see this post: <br /> <br /><a href="http://www.mikeash.com/pyblog/friday-qa-2009-11-27-using-accessors-in-init-and-dealloc.html">http://www.mikeash.com/pyblog/friday-qa-2009-11-27-using-accessors-in-init-and-dealloc.html</a>f29f8dfa825bbdf47d0c8ae643b38110Sat, 29 May 2010 23:04:02 GMTKeith Selbee - 2010-05-29 10:46:21http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsIn your first code example above, why are you setting _b's A ref to nil? If this is the B dealloc there's no chance it's going to call A later, right?804036e370b0fc959c80804ec0fd6654Sat, 29 May 2010 10:46:21 GMTmikeash - 2010-05-04 21:09:28http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#comments<b>jt:</b> And thanks very much for saying so, always nice to see.8e9b3ee5afcd2b7d57eb824aa362c26dTue, 04 May 2010 21:09:28 GMTjt - 2010-05-01 20:35:03http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsMike: Just wanted to say how much I appreciate the Friday sessions. Thanks.111649b2ceea52732bc969969f8e58cbSat, 01 May 2010 20:35:03 GMTJames Walker - 2010-05-01 07:18:44http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsJeff, what's the advantage of using a notification, rather than having the target object have a nonretained pointer to the owner object, and sending it a message directly when the timer fires?970549b377654c826661947019c92bb0Sat, 01 May 2010 07:18:44 GMTSteven Degutis - 2010-04-30 19:28:26http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsJeff, that's a really cool solution. Essentially you're adding an intermediary object (NSNotificationCenter) between the two objects involved, which breaks the retain-cycle by referring to your target via simple pointer assignment. Very clever!01bba5b2d877e7a902a93d3b85822629Fri, 30 Apr 2010 19:28:26 GMTJeff Johnson - 2010-04-30 17:30:59http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsI like to avoid timer retain cycles by creating a special timer target class that posts a notification when the timer fires. The owner of the timer observes the timer target notification. The timer retains the special target class rather than the owner of the timer, so there's no retain cycle.fa740961cfee5741f20a6dfd7db20d73Fri, 30 Apr 2010 17:30:59 GMTAlex Blewitt - 2010-04-30 17:25:02http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsDid you meain 'retaining' cycles for the subject of the post? There's a missing 'in' somewhere, I think7a5390471c721ed90865e91662ce5253Fri, 30 Apr 2010 17:25:02 GMTcygnl7 - 2010-04-30 16:54:55http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsNever mind. I had the ownership backwards.0c32d2e9607bc2e9e479a7a6f22852b8Fri, 30 Apr 2010 16:54:55 GMTcygnl7 - 2010-04-30 16:53:26http://www.mikeash.com/?page=pyblog/friday-qa-2010-04-30-dealing-with-retain-cycles.html#commentsIn the fixed NSTimer example, self is still the parameter to target. Doesn't that still create a retain cycle? Shouldn't the target be the new child Impl class?7485c4f9fb365656818cf95ce8bb26a9Fri, 30 Apr 2010 16:53:26 GMT