编写等效代码为iOS中9
在我的应用我有下面的代码段:编写等效代码为iOS中9
__weak __typeof(self)weakSelf = self;
_pingTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
repeats:YES
block:^(NSTimer * _Nonnull timer)
{
__strong __typeof(weakSelf)strongSelf = weakSelf;
[strongSelf pingWithBlock:nil];
}];
这完全在iOS的10+,但我需要的应用程序支持的iOS 9为好。所以我需要提供一种适用于两者的方法。
我尝试这样做:
__weak __typeof(self)weakSelf = self;
_pingTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:weakSelf
selector:@selector(pingWithBlock:)
userInfo:nil
repeats:YES];
pingWithBlock方法是在同一个类中定义的,它是一个实例方法。
但是,这似乎不工作,这意味着我得到一个不好的内存访问崩溃。
如果有人有任何建议,将不胜感激。
编辑:下面 感谢@dgatwood解释代码修复该问题
- (void)autoPing
{
_pingTimer = [NSTimer scheduledTimerWithTimeInterval:self.autoCheckInterval
target:self
selector:@selector(pingWithBlock)
userInfo:nil
repeats:YES];
}
-(void)pingWithBlock
{
[self pingWithBlock:nil];
}
这是一种奇怪的。 NSTimer保留其目标。也许这不会发生在这种情况下,因为__weak
,但我认为它无论如何。 *耸耸肩*
无论哪种方式,这听起来像一个多线程竞争条件:
- 您的计时器没有保留的对象,因此它可能消失在任何时间。
- 别的东西是保留对象。
- 计时器计划在构造计时器时正在运行的线程的runloop中。
- 在别的线程中引用另一个对象的引用。
- 计时器在第一个线程中触发,并且归零弱引用未归零,因为该对象仍处于摧毁自身的中途。
- 发生崩溃。
最好的解决方法是让计时器保留目标对象(通过删除所有的weakSelf
东西)。如果计时器是重复计时器,请提供一种方法来允许处理封闭对象的代码取消该计时器,并且要小心始终调用它。
谢谢你,阅读槽你的解释给我带来了正确的实施! –
“也许这不会因为__weak而发生在这种情况下”这是无关紧要的。弱和强是本函数中局部变量的语义。它与如何通过论证无关。只有*值*被传递 - 它与变量或所有权语义无关。 – newacct
我相信也是这种情况,这就是为什么行为没有意义,除非编译器中存在ARC错误,因为NSTimer根据文档保留其对象。 Self被自称的当前方法强制保留(否则该代码不会运行),并且定时器增加了保留计数,这意味着它应该由定时器保留,即使在其他任何保留它停止执行之后所以,在这个过程的任何时候,保留数不可能降到0,除非我错过了一些非常微妙的东西。 – dgatwood
你的'pingWithBlock:'方法在哪里?并定义“不起作用”。 – rmaddy
刚刚更新了我的问题 –
不要编辑你的问题的答案。发布实际的答案。 – rmaddy