【问题标题】:Write equivalent code for in iOS 9在 iOS 9 中编写等效代码
【发布时间】:2017-06-01 22:31:00
【问题描述】:

在我的应用程序中,我有以下一段代码:

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

【问题讨论】:

  • 您的pingWithBlock: 方法在哪里?并定义“不起作用”。
  • 刚刚更新了我的问题
  • 不要用答案编辑你的问题。发布实际答案。

标签: ios objective-c block nstimer


【解决方案1】:

这有点奇怪。 NSTimer 保留它的目标。由于__weak,在这种情况下可能不会发生这种情况,但我认为它还是发生了。 *耸耸肩*

不管怎样,这听起来像是一个多线程竞争条件:

  • 您的计时器没有保留该对象,因此它随时可能消失。
  • 其他东西正在保留该对象。
  • 定时器在构造定时器时正在运行的线程的运行循环中调度。
  • 其他东西在另一个线程中处理对对象的引用。
  • 计时器在第一个线程中触发,归零弱引用尚未归零,因为对象仍在销毁自身的一半。
  • 发生崩溃。

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

【讨论】:

  • 谢谢,通过您的解释,我找到了正确的实现方式!
  • “也许在这种情况下不会发生,因为 __weak” 这无关紧要。弱和强是这个函数中局部变量的语义。它与参数的传递方式无关。只传递了一个——它与变量或所有权语义无关。
  • 我相信情况也是如此,这就是为什么除非编译器中存在 ARC 错误,否则该行为毫无意义,因为 NSTimer 根据文档保留其对象。 Self 被 self 上的当前方法强烈保留(否则此代码将不会运行),并且计时器会增加保留计数,这意味着它应该由计时器保留,即使在其他保留它停止执行之后也是如此因此,除非我遗漏了一些非常微妙的东西,否则保留计数不可能在该过程中的任何时候降至 0。
猜你喜欢
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
  • 2021-01-10
  • 1970-01-01
  • 1970-01-01
  • 2020-02-27
  • 1970-01-01
相关资源
最近更新 更多