在iOS 9中编写等效代码

时间:2017-06-01 22:31:00

标签: ios objective-c block nstimer

在我的应用中,我有以下代码:

__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];
}

1 个答案:

答案 0 :(得分:0)

这有点奇怪。 NSTimer保留其目标。也许这种情况不会因为__weak而发生,但我认为无论如何都是这样。 * *耸肩

无论哪种方式,这听起来像多线程竞争条件:

  • 您的计时器不会保留该物体,因此它可能随时消失。
  • 其他 保留对象。
  • 计时器安排在构造计时器时运行的线程的runloop中。
  • 其他东西在另一个线程中处理对象的引用。
  • 计时器在第一个线程中触发,并且归零弱引用没有归零,因为该对象仍然在破坏自己的中途。
  • 发生崩溃。

最好的解决方法是让计时器保留目标对象(通过删除所有weakSelf内容)。如果计时器是重复计时器,请提供一种方法,允许处理封闭对象的代码取消该计时器,并小心始终调用它。