最近我们app感觉内存暴涨,肯定是有了内存问题。经过几天奋战整理了成吨的内存泄漏点,每一种抽一个代表出来作为记录。
这个博客还有别的案例:
http://blog.reigndesign.com/blog/debugging-retain-cycles-in-objective-c-four-likely-culprits/
1,JTNavigationController 中的循环引用
关键代码:
- (void)setJt_navigationController:(JTNavigationController *)navigationController { objc_setAssociatedObject(self, @selector(jt_navigationController), navigationController, OBJC_ASSOCIATION_ASSIGN); // OBJC_ASSOCIATION_RETAIN => OBJC_ASSOCIATION_ASSIGN }
2,有 presentViewController 没有对应的 dismissViewController
// 如果是 present 出来的,必须 dismiss,不然会有内存泄漏 __weak typeof(self) wself = self; [selfdismissViewControllerAnimated:YEScompletion:^{ [wself _showLoginController]; }];
3,delegate 写成了 strong
// @property (nonatomic, strong) id<NewsContentViewControllerDelegate> delegate; @property (nonatomic, weak) id<NewsContentViewControllerDelegate> delegate;
4,
NSPointerArray 弱指针使用不当
- (NSPointerArray *)listeners { if (!_listeners) { // _listeners = [[NSPointerArray alloc] init]; _listeners = [NSPointerArrayweakObjectsPointerArray]; } return _listeners; }
5,定时器没有关闭
这里是一个在后台循环刷票据的定时器,注销之后定时器依旧活跃(每次)
解决方案是注销之后把定时器关掉。
- (void)_beginRefreshToken { AccountManager* accountManager = [AccountManager sharedInstance]; if ([accountManager isGuestMode]) { // 游客模式不需要刷新票据return; } if (!self.refreshTicketTimer) { self.refreshTicketTimer = [NSTimerscheduledTimerWithTimeInterval:kRefreshTicketIntervaltarget:selfselector:@selector(_onRefreshTicketTimer:)userInfo:nilrepeats:YES]; } }
6,block 循环引用
这里的例子是, GuideViewController 引用了 LicenseViewController,LicenseViewController 引用了 acceptHandler
而 acceptHandler 又捕获并强引用了 GuideViewController
更多详细例子和解决方案可以参考这个博客
- (void)_loadLicenseView { LicenseViewController* controller = [[LicenseViewController alloc] initWithNibName:nilbundle:nil]; [selfaddChildViewController:controller]; __weak __typeof(self) wself = self; controller.acceptHandler = ^{ // [self _finishGuide]; [wself _finishGuide]; }; }
关于 block 循环引用问题,我们定义了两个公用的宏:
#define YYWeakSelf(wself) __weak __typeof(self) wself = self #define YYStrongSelf(sself, wself) __strong __typeof(wself) sself = wself