计时器是一种很方便的对像。由于定时器灰保留起目标对象,所以会造成循环引用。内存释放的了。大家可以建立一个NSTimer然后在dealloc看看会不会进来。
有二种方法解决
1:使用block 如果block里面用的是一个弱指针的话block就会对外面的对象产生弱应用 。
__weak typeof(self) weakSelf = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
[weakSelf timerTest];
}];
看到这里有人会说我这样不也可以吗
__weak typeof(self) weakSelf = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:weakSelf selector:@selector(timerTest) userInfo:nil repeats:YES]
运行你会发现还是不行,为什么呢?其实在NSTimer 里面你会发现aTarget在源代码里面已经被强引用了所以外面不管怎么修改都是不行的。block则不一样。
2.建立一个中间类 在中间类把aTarget弱应用
#import <Foundation/Foundation.h>
@interface LSProxy : NSProxy
+ (instancetype)proxyWithTarget:(id)target;
@property (weak, nonatomic) id target;
#import "LSProxy.h"
@implementation LSProxy
+ (instancetype)proxyWithTarget:(id)target
{
// NSProxy对象不需要调用init,因为它本来就没有init方法
LSProxy *proxy = [LSProxy alloc];
proxy.target = target;
return proxy;
}
//消息转发 交给其他对象处理
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
return [self.target methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
[invocation invokeWithTarget:self.target];
}
然后在其他地方调用
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[LSProxy proxyWithTarget:self] selector:@selector(timerTest) userInfo:nil repeats:YES];
为什么要用NSProxy?NSProxy事专门用来处理消息转发的效率比NSObject高
网友评论