__weak typeof(self) weakSelf = self; [btn bk_addEventHandler:^(id sender) { if (_activity.source == ATASyncTypeInvitation) { ATAViewActivityInvitationViewController *vc = (ATAViewActivityInvitationViewController *)[[ATAViewActivityInvitationViewController alloc] initWithActivity:_activity]; [weakSelf.navigationController pushViewController:vc animated:YES]; } else { ATAEditCalendarEventViewController *vc = [[ATAEditCalendarEventViewController alloc] initWithActivity:_activity]; [weakSelf.navigationController pushViewController:vc animated:YES]; } forControlEvents:UIControlEventTouchUpInside]; 这段代码看起来没有问题,但是在实际中却遇到了 Controller 无法回收的尴尬。像前一篇Block 中循环引用导致内存泄漏样例一则提到的那样,加上 weak 修饰本来就可以万事大吉还是出了问题。所以问题在哪里呢? 原来是调用了_activity导致的,改成weakSelf.activity就好了,或者把 activity 做一份 weak 版本也行。 CFTypeRef 其实是 MRCARC 时代的人可能都不知道 MRC 怎么用的,很可惜 CoreFoundation 框架下的对象全是需要手动释放的。也就是说 ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); 这样通过 xxxxxCreate 函数生成并自己持有的对象是需要自己手动调用 CFRelease来释放,否则会内存泄漏。然而 ABRecordRef abRecordRef = [participant ABRecordWithAddressBook:addressBook]; 这却不能调用 CFRelease 函数来释放,因为这个函数生成的对象自己并不持有,不能释放自己不持有的对象。这个函数在生成对象并 return 的时候将对象注册到了 AutoReleasePool 延长生命周期,只要 pool 生命周期结束其内的对象跟着一起销毁。
__weak typeof(self) weakSelf = self; [btn bk_addEventHandler:^(id sender) { if (_activity.source == ATASyncTypeInvitation) { ATAViewActivityInvitationViewController *vc = (ATAViewActivityInvitationViewController *)[[ATAViewActivityInvitationViewController alloc] initWithActivity:_activity]; [weakSelf.navigationController pushViewController:vc animated:YES]; } else { ATAEditCalendarEventViewController *vc = [[ATAEditCalendarEventViewController alloc] initWithActivity:_activity]; [weakSelf.navigationController pushViewController:vc animated:YES]; } forControlEvents:UIControlEventTouchUpInside];
这段代码看起来没有问题,但是在实际中却遇到了 Controller 无法回收的尴尬。像前一篇Block 中循环引用导致内存泄漏样例一则提到的那样,加上 weak 修饰本来就可以万事大吉还是出了问题。所以问题在哪里呢? 原来是调用了_activity导致的,改成weakSelf.activity就好了,或者把 activity 做一份 weak 版本也行。 CFTypeRef 其实是 MRCARC 时代的人可能都不知道 MRC 怎么用的,很可惜 CoreFoundation 框架下的对象全是需要手动释放的。也就是说 ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); 这样通过 xxxxxCreate 函数生成并自己持有的对象是需要自己手动调用 CFRelease来释放,否则会内存泄漏。然而 ABRecordRef abRecordRef = [participant ABRecordWithAddressBook:addressBook]; 这却不能调用 CFRelease 函数来释放,因为这个函数生成的对象自己并不持有,不能释放自己不持有的对象。这个函数在生成对象并 return 的时候将对象注册到了 AutoReleasePool 延长生命周期,只要 pool 生命周期结束其内的对象跟着一起销毁。
这段代码看起来没有问题,但是在实际中却遇到了 Controller 无法回收的尴尬。像前一篇Block 中循环引用导致内存泄漏样例一则提到的那样,加上 weak 修饰本来就可以万事大吉还是出了问题。所以问题在哪里呢?
原来是调用了_activity导致的,改成weakSelf.activity就好了,或者把 activity 做一份 weak 版本也行。
_activity
weakSelf.activity
activity
ARC 时代的人可能都不知道 MRC 怎么用的,很可惜 CoreFoundation 框架下的对象全是需要手动释放的。也就是说
CoreFoundation
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); 这样通过 xxxxxCreate 函数生成并自己持有的对象是需要自己手动调用 CFRelease来释放,否则会内存泄漏。然而 ABRecordRef abRecordRef = [participant ABRecordWithAddressBook:addressBook]; 这却不能调用 CFRelease 函数来释放,因为这个函数生成的对象自己并不持有,不能释放自己不持有的对象。这个函数在生成对象并 return 的时候将对象注册到了 AutoReleasePool 延长生命周期,只要 pool 生命周期结束其内的对象跟着一起销毁。
这样通过 xxxxxCreate 函数生成并自己持有的对象是需要自己手动调用 CFRelease来释放,否则会内存泄漏。然而
xxxxxCreate
CFRelease
ABRecordRef abRecordRef = [participant ABRecordWithAddressBook:addressBook]; 这却不能调用 CFRelease 函数来释放,因为这个函数生成的对象自己并不持有,不能释放自己不持有的对象。这个函数在生成对象并 return 的时候将对象注册到了 AutoReleasePool 延长生命周期,只要 pool 生命周期结束其内的对象跟着一起销毁。
这却不能调用 CFRelease 函数来释放,因为这个函数生成的对象自己并不持有,不能释放自己不持有的对象。这个函数在生成对象并 return 的时候将对象注册到了 AutoReleasePool 延长生命周期,只要 pool 生命周期结束其内的对象跟着一起销毁。