今天一直在释放一个类对象B(这个类中有一个timer),根据arc的原理来说, B的retainCount为0时,就会调用dealloc。但是当为我把B=nil,没有进入dealloc。
-(void)dealloc
{
[timer invalidate];
timer = nil;
}
后来经过朋友提醒知道,nstimer对B类有引用,也就是在初始化时对target有retain.
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 self selector:@selector( logout: ) userInfo:nil repeats:YES];
后来把self改为__weak,发现也不行。
__weak id weakSelf = self;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:weakSelf selector:@selector( logout: ) userInfo:nil repeats:YES];
最终在stackoverflow里面找到了一种使用代理的方法。
http://stackoverflow.com/questions/16821736/weak-reference-to-nstimer-target-to-prevent-retain-cycle
单独建立一个WeakTimerTarget
@interface WeakTimerTarget : NSObject
{
__weak id target;
SEL selector;
}
-(id)initWithTarget:(id)tg selector:(SEL)sel;
- (void)timerDidFire:(NSTimer *)timer;
@end
@implementation WeakTimerTarget
-(id)initWithTarget:(id)tg selector:(SEL)sel
{
self = [super init];
target = tg;
selector = sel;
return self;
}
- (void)timerDidFire:(NSTimer *)timer
{
if(target)
{
[target performSelector:selector withObject:timer];
}
else
{
[timer invalidate];
}
}
@end
在B类中这样使用:
WeakTimerTarget *weakTarget = [[WeakTimerTarget alloc] initWithTarget:self selector:@selector(logout:)];
[NSTimer scheduledTimerWithTimeInterval:1.0 target:weakTarget selector:@selector( timerDidFire: ) userInfo:nil repeats:YES];
这样就可以解决不能释放内存的问题了,但是为什么使用__weak self 和 __strong self效果是一样的还不知道为什么,希望大家指教。