我用的是这样的NSTimer:

timer = [NSTimer scheduledTimerWithTimeInterval:30.0f target:self selector:@selector(tick) userInfo:nil repeats:YES];

当然,NSTimer将保留目标,这将创建一个保留周期.此外,self不是UIViewController,所以我没有像viewDidUnload这样的东西,可以使计时器失效以打破循环.所以我想知道我是否可以使用弱引用:

__weak id weakSelf = self;
timer = [NSTimer scheduledTimerWithTimeInterval:30.0f target:weakSelf selector:@selector(tick) userInfo:nil repeats:YES];

我听说计时器must会失效(我想是从运行循环中释放它).但我们可以在我们的交易中做到,对吗?

- (void) dealloc {
    [timer invalidate];
}

这是一个可行的 Select 吗?我见过很多人处理这个问题的方法,但我还没有见过.

推荐答案

拟议守则:

__weak id weakSelf = self;
timer = [NSTimer scheduledTimerWithTimeInterval:30.0f target:weakSelf selector:@selector(tick) userInfo:nil repeats:YES];

具有以下效果:(i)对self 的引用较弱;(ii)读取该弱参考以提供指向NSTimer的指针.它不会产生创建一个带有弱引用的NSTimer的效果.该代码与使用__strong引用之间的唯一区别是,如果self在给定的两行之间被释放,那么您将把nil传递给计时器.

你能做的最好的事情就是创建一个代理对象.比如:

[...]
@implementation BTWeakTimerTarget
{
    __weak target;
    SEL selector;
}

[...]

- (void)timerDidFire:(NSTimer *)timer
{
    if(target)
    {
        [target performSelector:selector withObject:timer];
    }
    else
    {
        [timer invalidate];
    }
}
@end

然后你会这样做:

BTWeakTimerTarget *target = [[BTWeakTimerTarget alloc] initWithTarget:self selector:@selector(tick)];
timer = [NSTimer scheduledTimerWithTimeInterval:30.0 target:target selector:@selector(timerDidFire:) ...];

或者甚至向表单+scheduledTimerWithTimeInterval:target:selector:...的BTWeakTimerTarget添加一个类方法,以创建该代码的更简洁的表单.你可能想要公开真实的NSTimer,这样你就可以使用它,否则建立的规则将是:

  1. 真正的目标没有被计时器保留;
  2. 在真正的目标开始(可能已经完成)解除分配后,计时器将触发一次,但该触发将被忽略,计时器随即失效.

Objective-c相关问答推荐

反编译ARM64和理解分支目标边界

UITableView/UITableViewCell 点击事件响应?

将 CSS 插入 UIWebView / WKWebView 中加载的 HTML

为什么我的 UIButton 的内部修饰事件没有被调用?

iOS 正确使用 @weakify(self) 和 @strongify(self)

右对齐的 UITextField 空格键在 iOS 7 中不前进光标

iOS:将 URL 解析为段

Objective C - 为什么常量以 k 开头

setStatusBarHidden 在 iOS 9.0 中已弃用

如何与 UITableView 一起滚动标题?

Objective-C 中的 const 与静态 NSStrings

更改 UIBarButtonItem 的 Tint colored颜色

Objective-C:前向类声明

Xcode 在您的 keys 串中找不到此配置文件的有效私有证书/有效密钥对

如何从输入 IB 的 UILabel 文本中插入新行 \n?

从 URL Objective C 获取图像

获取临时目录中文件的文件路径和 URL

如何减小使用 UIImagePickerController 创建的视频的文件大小?

如何阻止 NSNotification 中的观察者调用两次?

CALayer:仅在一侧添加边框