关闭

弱引用NSTimer对象

1003人阅读 评论(0) 收藏 举报
分类:
      

不要忘记 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


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1625682次
    • 积分:16921
    • 等级:
    • 排名:第606名
    • 原创:256篇
    • 转载:138篇
    • 译文:3篇
    • 评论:161条
    最新评论