在arc下,xcode已经把大多数内存问题给我们解决了,但是不是所有
1,block会引起内存泄漏,如果block回调中用到了self的引用,但是没有加_weak 声明,则self将会被block copy到内部增加一次引用计数,形成循环引用。
例如下面的代码中(如果单例中持有block)self将永远不会被释放。
[[YYBDatahub sharedInstance] fetch_cardWithComplete:^(id responseObj, NSError *error) {
[self refreshText];
}];
解决办法是在工程的constant.h文件中定义一个define:
#define kCreateWeakSelf __weak __typeof(&*self)weakSelf = self
然后上面的代码修改为
kCreateWeakSelf;
[[YYBDatahub sharedInstance] fetch_cardWithComplete:^(id responseObj, NSError *error) {
[weakSelf refreshText];
}];
2,delegate声明为strong会造成循环引用,delegate也不能用assign来声明,因为assign可能会造成野指针,应该用weak声明,工程中可能有人习惯用superVC,parentVC等方式来实现delegate类似的功能,这时候要尤其注意。例如:
@property (nonatomic,weak) id<YYBBirthdaySelectViewDelegate> delegate;
3,有的时候创建一个view会加到windows上,但是最后为了下次不用创建就能使用,所以只将alpha设为0或hidden为YES,没有从windows上移除,这时候就造成了内存泄漏,甚至有的下次没有重用之前创建的view,重复创建,造成view越来越多,泄漏越来越大。
4,可能有的数据放到了单例中保存,但是没有指定在何种情况下清空保存在单例中的数据,这时候也会造成泄漏。
5,NSTimer会强引用self,所以用完之后要调用
[_notificationTimer invalidate];
方法来手动释放对self的强引用
综上所述,是我目前遇到的arc下所有内存泄漏的情况。
最后给大家提供一个神器,FBAllocationTracker,facebook出的一款监测alloc,dealloc的工具,
(1)在main.m中加入
[[FBAllocationTrackerManager sharedManager] startTrackingAllocations];
[[FBAllocationTrackerManager sharedManager] enableGenerations];
(2)在首页调用一下获取当前alloc,但未dealloc的类,最后NSLog一下即可看到是否有泄漏的情况。
NSArray *instances =[[FBAllocationTrackerManager sharedManager] instancesOfClasses:@[
[YYBAlbumChoiceViewController class]];
我是用简便的方式把所有类名批量操作的方式加到了这个里边,监测了app中存在的大部分内存泄漏,可以说是神器。唯一不足的是多个tabbar的时候,FBAllocationTracker监测的不准,监测tabbar没有释放,但实际上我把main.m中关于AllocationTracker的代码注掉后,tabbar是走了dealloc方法的,所以我大胆假设FBAllocationTracker强引用了每个tabbar来实现的监测功能。