gpt4 book ai didi

objective-c - NSOperation 内部的魔力——它如何观察 isFinished 键以便 completionBlock 始终运行?

转载 作者:搜寻专家 更新时间:2023-10-30 20:25:17 25 4
gpt4 key购买 nike

示范

- (void)test_NSOperationCallsCompletionBlockWhenFinished {
__block BOOL flag = NO;

NSOperation *operation = [NSOperation new];

operation.completionBlock = ^{
NSLog(@"Hunting NSOperation internals: %@", [NSThread callStackSymbols]);

flag = YES;
};

[operation start];

while (flag == NO);

STAssertTrue(flag, nil);
}

给我以下输入:

2013-07-28 19:59:44.690 SACompositeOperationsApp[99551:3103] Hunting NSOperation internals: (
0 SACompositeOperationsApp 0x000000010005bbd9 __68-[SAOperationTests test_NSOperationCallsCompletionBlockWhenFinished]_block_invoke + 41
1 Foundation 0x00007fff8a27bb25 __+[__NSOperationInternal _observeValueForKeyPath:ofObject:changeKind:oldValue:newValue:indexes:context:]_block_invoke_3 + 55
2 libdispatch.dylib 0x00007fff8abd9a82 _dispatch_call_block_and_release + 18
3 libdispatch.dylib 0x00007fff8abdb083 _dispatch_async_f_redirect_invoke + 112
4 libdispatch.dylib 0x00007fff8abda961 _dispatch_worker_thread2 + 255
5 libsystem_c.dylib 0x00007fff91ce13da _pthread_wqthread + 316
6 libsystem_c.dylib 0x00007fff91ce2b85 start_wqthread + 13
)

背景

我正在用我的自定义 NSOperation 子类做一些实验 - 我试图在 isFinished 属性上添加我自己的观察者,它们按预期工作得很好。

这些实验让我惊讶于 NSOperation 如何根据其对 isFinished 属性更改的观察来调用其 completionBlocks -

我不明白的是,这就是为什么这个问题是我的 isFinished 属性的观察者从不干扰 NSOperation 的观察者(如果我添加它们,删除它们。 ..),所以 observe isFinished -> invoke completionBlock when it become YES 逻辑被封装得很好,让我可以自由地做额外的 KVO 观察,没有任何问题:

1) 我做了几个测试,表明 NSOperation 在其 -[NSOperation init] 中对属性更改观察进行了某种神奇的订阅 - 我不知道 是什么那里正在进行,但我已确保它与“isFinished->completionBlock”相关的东西正在那里。我想知道除了常见的 -[NSObject init] 逻辑之外还做了什么?

2) NSLog 输出显示它不是 NSOperation 类,而是一些神秘的 NSOperationInternal 被调用了 observeValueForKeyPath:ofObject:changeKind:oldValue:newValue:indexes:context: 最终调用了 completionBlock。

3) 就我的理解而言,GNUStep implementation of NSOperation在实现细节上有所不同(至少在描述的 isFinished-completionBlock 方面,参见,例如 _finish method),这就是为什么我不能用它作为帮助来理解 Apple 的方法NSOperation是怎么写的。


注意

我没有任何 Unresolved 问题,我只是想在isFinished observing -> completionBlock invocation方面更深入地了解NSOperation内部是如何工作的。

我不想看到:“Apple 的内部是隐藏的,非 Apple 工程师不可能知道”。我希望看到一个确实包含对该主题的深刻见解的答案。

最佳答案

这是我目前对 NSOperation 生命周期的了解,虽然不多,但足以回答我最初的问题:

  1. NSOperation 在它的 -init 方法中注册了它的 isFinished 属性的 KVO 观察。这意味着即使我从未运行过 -start (main) 方法(我对自定义 NSOperation 子类进行了一些实验以确定这一点),也会记录观察结果。相应的注销是在 NSOperation 的 -dealloc 方法中完成的(我无法证明这一点,但它确实是唯一可以发生的地方)。

  2. 为了使 KVO 成为可能并且“私有(private)”NSOperation 有一些内部容器类 NSOperationInternal,它封装了 NSOperation 的自己的 KVO 例程,让我可以自由地做我的自定义 KVO,当我想为我的 NSOperation 类的自定义子类的实例。在我自定义的 NSOperation 子类中,我可以使用我自己的 observeValueForKeyPath:ofObject:change:context: 方法实现,而不用担心与 NSOperation 自己的 KVO 有任何可能的冲突,因为它不会干扰在 NSOperationInternal 中实现的这个方法。

P.S. 关于“魔法”这个词——我知道幕后都是 KVO——所以这里对 KVO 本身并不感到惊讶。我惊讶的是 KVO 在具体细节上是如何应用于 NSOperation 的:这里没有什么神奇的东西,但它并不是很明显,当我第一次开始引入我自己的 KVO 并对可能的干扰产生怀疑时。

关于objective-c - NSOperation 内部的魔力——它如何观察 isFinished 键以便 completionBlock 始终运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17910902/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com