【问题标题】:NSOperation ready but not starting on iOS 7NSOperation 已准备就绪,但未在 iOS 7 上启动
【发布时间】:2013-10-08 20:15:08
【问题描述】:

我们创建了一个操作框架来添加一些在基类中没有的功能(例如跟踪成功/失败)。父操作通常是非并发的,并且可能仅用于管理子操作。子操作通常是并发的(异步下载 xml 和媒体)。

当我们在 iOS 7 上运行我们的应用程序时,将一些操作添加到操作队列中,大约 3/4 的操作完成,然后应用程序似乎挂起。

当我在调试器中暂停应用程序并检查队列中的操作 (sOpQueue.operations) 时,其中许多已准备好运行(isReady 返回 TRUE),但显然它们都没有执行(isExecuting 返回 FALSE ,并且我没有看到任何线程上运行任何操作的证据)。

这是 iOS 7 的新问题。

当我增加或减少并发操作的数量时,行为似乎没有改变。

有没有人对如何确定为什么没有开始准备好的操作有任何建议?

谢谢, 查克

【问题讨论】:

  • 我在 Apple 的开发者论坛上发布了同样的问题:devforums.apple.com/message/904947#904947 Apple 支持专家的回应是,最重要的 isReady 是:“远离人迹罕至的道路”。因此,我们正在重新评估我们的方法。

标签: ios nsoperation nsoperationqueue


【解决方案1】:

您是否发出isReady Key Value Observing 通知?

例如,我使用一个属性:

@property (nonatomic, getter = isReady) BOOL ready;

然后有一个自定义的setter:

- (void)setReady:(BOOL)ready
{
    [self willChangeValueForKey:@"isReady"];
    _ready = ready;
    [self didChangeValueForKey:@"isReady"];
}

以及调用super的自定义getter:

- (BOOL)isReady
{
    return _ready && [super isReady];
}

而且,因为你实现了 setter 和 getter,你必须手动合成 @implementation 开头的属性(通常你不必再这样做了,但是如果你实现了所有的自定义访问器, 你得手动@synthesize):

@synthesize ready = _ready;

然后,当满足以下两个条件时,操作开始:

  • ready属性设置为YES(注意,使用setter,而不是直接使用ivar);

    self.ready = YES;
    

    [self setReady:YES];
    
  • 满足所有其他标准 NSOperation 标准(例如,操作之间的依赖关系、遵守 maxConcurrentOperationCount、考虑优先级等)。

【讨论】:

  • 我们没有维护一个单独的属性,而是在就绪状态发生变化时发出 KVO 通知调用。
  • @ChuckDoucette 好吧,在没有代码示例的情况下我不知道该说什么,因为上述两种方法在 iOS7 中都可以正常工作(我在发布之前都测试了)。我怀疑您的 isReady 方法、关联的 KVO 或其他东西(如依赖项、队列挂起等)中存在一些简单的错误。我建议为您遇到的问题创建一个最简单的演示,并与我们分享(当然,假设在进行此练习的过程中,您不只是弄清楚出了什么问题)。
  • 唯一可能使操作无法运行的是 (a) 挂起的队列; (b) 未加入队列; (c) isReady 方法没有返回正确的值,并且在更改isReady 返回值之前/之后没有调用will/didChangeValueForKey; (d) 一些奇怪的依赖相关问题(一些依赖操作未开始,未完成等)。这些是唯一能想到的事情。但是我没有看到任何iOS 7的问题,并且我做了很多操作的东西。
  • 刚刚偶然发现了这个答案,我想补充一点,如果您为isReady 创建属性和自定义设置器,您还应该覆盖获取器并返回您自己的变量的结果 + @ 987654341@。如果您不这样做,则某些事情(例如依赖项)可能会中断(如果有的话)。来自文档:“如果这样做,您的自定义实现应该调用 super 并将其返回值合并到对象的就绪状态中。”
【解决方案2】:

我敢打赌你有并发操作没有正确完成。增加并发操作的数量,看看是否可以在挂起之前运行更长时间。然后找出为什么你的并发操作没有正确设置 isFinished。

【讨论】:

  • 我试图增加(和减少)并发操作的数量。两者似乎都没有任何效果。未完成并发操作是一个很好的猜测 - 但我们的操作队列中剩下的操作似乎都没有正在执行([op isExecuting] 返回 FALSE,并且似乎没有操作线程处于活动状态。
  • 您是否有可能对这些操作设置了依赖项?您能否确认依赖关系已成功完成?而且你没有循环依赖?
猜你喜欢
  • 2015-07-01
  • 2020-09-22
  • 1970-01-01
  • 1970-01-01
  • 2015-04-30
  • 2012-02-15
  • 1970-01-01
  • 1970-01-01
  • 2019-11-21
相关资源
最近更新 更多