您的位置:首页 > 其它

弱引用NSTimer对象

2015-07-09 23:12 260 查看
      

不要忘记 NSTimer 会 retain它的对象,意味着如果你的timer的 target 也是 NSTimer的 拥有者的时候,很容易就进入一个循环引用。

你可以通过一个 代理的delegate来 绕过这个, 这个代理对象拥有这个真正target的 weak 引用。 

@interface
TMWeakTimerTarget :
NSObject

- (instancetype)initWithTarget:(id)target selector:(SEL)selector;

- (void)timerDidFire:(NSTimer *)timer;

@end

@interface
TMWeakTimerTarget()

@property (nonatomic,
weak) id target;

@property (nonatomic) SEL selector;

@end

@implementation
TMWeakTimerTarget

#pragma mark - Initialization

- (instancetype)initWithTarget:(id)target selector:(SEL)selector {

    if (self = [super init]) {

        _target = target;

        _selector = selector;

    }

    return self;

}

- (id)init {

    return [self initWithTarget:nil selector:nil];

}

#pragma mark - TMWeakTimerTarget

- (void)timerDidFire:(NSTimer *)timer {

    if (self.target) {

        // `performSelector:` would generate a potential leak warning (http://stackoverflow.com/a/7073761/503916)

        objc_msgSend(self.target,
self.selector);

    }

    else {

        [timer invalidate];

    }

}

@end

你可以创建一个 NSTimer的 Category ,来更容易的使用这个类

/**

 *  Method that can be used in favor of `scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:` in case the target retains the timer instance. Using the aforementioned method would create a retain cycle in this
case.

 */

@interface
NSTimer (RetainCyclePrevention)

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval 

                                 weakTarget:(id)target 

                                   selector:(SEL)selector 

                                   userInfo:(id)userInfo 

                                    repeats:(BOOL)yesOrNo;

@end

@implementation
NSTimer (RetainCyclePrevention)

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval 

                                 weakTarget:(id)target 

                                   selector:(SEL)selector 

                                   userInfo:(id)userInfo 

                                    repeats:(BOOL)yesOrNo {

    return [self scheduledTimerWithTimeInterval:timeInterval 

                                         target:[[TMWeakTimerTarget alloc] initWithTarget:target 

                                                                                 selector:selector] 

                                       selector:@selector(timerDidFire:) 

                                       userInfo:userInfo 

                                        repeats:yesOrNo];

}

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: