导入方案
1.通过 cocoaPods 导入工程
2.手动下载项目源码拖进项目
导入后重新运行项目,然后逐个进入页面,退出页面,如果退出某个页面时,有弹窗,说明这个页面有内存泄露,有对象没被释放。
然后检查这些类对象有没有循环引用,一般造成循环的:
一.NSTimer 的 target 指向 self,然后 self 又持有 timer,所以我们可以把 target 指向中间者。
1.)WeakProxy:
创建一个继承NSProxy的子类WeakProxy,并实现消息转发的相关方法。
WeakProxy.h文件
@property (nonatomic, weak, readonly) id weakTarget;
- (instancetype)proxyWithTarget:(id)target;
- (instancetype)initWithTarget:(id)target;
WeakProxy.m文件
@implementation WeakProxy
- (instancetype)proxyWithTarget:(id)target {
return [[self alloc] initWithTarget:target];
}
-
(instancetype)initWithTarget:(id)target {
_weakTarget = target;
return self;
} -
(void)forwardInvocation:(NSInvocation *)invocation {
SEL sel = [invocation selector];
if ([self.weakTarget respondsToSelector:sel]) {
[invocation invokeWithTarget:self.weakTarget];
}
}
//返回方法的签名。
-
(NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
return [self.weakTarget methodSignatureForSelector:sel];
} -
(BOOL)respondsToSelector:(SEL)aSelector {
return [self.weakTarget respondsToSelector:aSelector];
}
@end
怎么使用
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:[WeakProxy proxyWithTarget:self] selector:@selector(timerStart:) userInfo:nil repeats:YES]; -
(void)dealloc {
[_timer invalidate];
NSLog(@“销毁了”);
}
这种方法,当一个控制器里使用多个 nstimer,每个 timer 都用[WeakProxy proxyWithTarget:self],退出这个页面时就会 crash
2.)Block:
创建NSTimer的分类NSTimer+UnretainCycle。
-
(NSTimer *)lhScheduledTimerWithTimeInterval:(NSTimeInterval)inerval
repeats:(BOOL)repeats
block:(void(^)(NSTimer *timer))block {
return [NSTimer scheduledTimerWithTimeInterval:inerval target:self selector:@selector(blcokInvoke:) userInfo:[block copy] repeats:repeats];
} -
(void)blcokInvoke:(NSTimer *)timer {
void (^block)(NSTimer *timer) = timer.userInfo;
if (block) {
block(timer);
}
}
怎么使用加粗样式
WEAKSELF
self.timer = [NSTimer mxScheduledTimerWithTimeInterval:0.5 repeats:YES block:^(NSTimer *timer) {
[weakSelf nextImage];
NSLog(@“执行了”);
}];
二。
block里 self没用弱引用
__weak typeof(self) wself = self;
self.collectionView.pc_header = [PCRefreshHeader headerWithWidth:SCREEN_WIDTH-tableviewWidth RefrshBlock:^{
[wself.pageArr replaceObjectAtIndex:wself.selectrow withObject:@(1)];
[wself getDataIsRefresh:YES];
[wself.collectionView.pc_footer resetNoMoreData];
}];
类方法里的 block没用弱引用 的类对象
__weak typeof(tableView) weakTableView = tableView;
PCHotArticlelistHeadView *headView = [[PCHotArticlelistHeadView alloc]initWithChannelsname:tempnames andbtnActionBlock:^(NSInteger index) {
[weakTableView getDataIsRefresh:NO];
}];