Contents
  1. 1. BlocksKit 中遇到的问题
  2. 2. CFTypeRef 其实是 MRC

最近老修一些内存泄漏问题,真是尴尬。

BlocksKit 中遇到的问题

__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 其实是 MRC

ARC 时代的人可能都不知道 MRC 怎么用的,很可惜 CoreFoundation 框架下的对象全是需要手动释放的。
也就是说

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

这样通过 xxxxxCreate 函数生成并自己持有的对象是需要自己手动调用 CFRelease来释放,否则会内存泄漏。
然而

ABRecordRef abRecordRef = [participant ABRecordWithAddressBook:addressBook];

这却不能调用 CFRelease 函数来释放,因为这个函数生成的对象自己并不持有,不能释放自己不持有的对象。这个函数在生成对象并 return 的时候将对象注册到了 AutoReleasePool 延长生命周期,只要 pool 生命周期结束其内的对象跟着一起销毁。

Contents
  1. 1. BlocksKit 中遇到的问题
  2. 2. CFTypeRef 其实是 MRC