你怎么知道 Objective-C 中的块参数是否正在转义?

How can you tell if a block parameter in Objective-C is escaping or not?

Long-time Swift 在这里开发,但大约十年没碰过 Objective-C,所以肯定生锈了。试图弄清楚如何判断块参数是否正在转义(也就是说,我知道是否使用弱引用,因为 non-escaping 块不需要它。)

例如,根据我的阅读,默认情况下在 Objective-C 中,块参数是隐式转义的(这与 Swift 顺便说一句相反。)如果你不想要那个,你必须使用 NS_NOESCAPE 注释,就像这样...

- (void)executeActions:(void (NS_NOESCAPE ^)(void))actions;

然而,我被告知的 enumerateObjectsUsingBlock 函数是 non-escaping,但我在 Apple 的文档中没有看到该方法的注释。实际上,他们根本不谈论转义或 non-escaping。他们只是列出了方法。

再次,here's the documentation

然后我尝试搜索 header 文件。我遇到了确实提到它的 NSArray.h,但我也没有看到 NS_NOESCAPE

https://github.com/.../NSArray.h(第 79 行)

(我认为这可能是一个 generated/scraped 页面,因此可能无法在此处找到该信息,您需要原始的 headers。不确定。再次,生锈。)

那么如何确定方法的块参数是否正在转义?

我认为这不再重要了...下面的代码编译和运行都没有问题,无论我如何尝试用 NS_NOESCAPE 破坏它。那和你把它放在哪里都没关系......

- (NSOperationQueue *)queue
{
    if ( ! _queue )
    {
        _queue = [[NSOperationQueue alloc] init];
    }

    return _queue;
}

- ( void ) t1:( NS_NOESCAPE void(^)(NSString *) ) b
{
    [self.queue addOperationWithBlock:^{
        b(@"a");
    }];
    [self t2:b];
}

- ( void ) t2:( void(^)(NSString *) ) NS_NOESCAPE b
{
    [self.queue addOperationWithBlock:^{
        b(@"b");
    }];
    [self t3:b];
}

- ( void ) t3:( void(NS_NOESCAPE ^)(NSString *) ) b
{
    [self.queue addOperationWithBlock:^{
        b(@"c");
    }];
    [self escape:b];
}

- ( void ) t4:( void(^)(void) ) NS_NOESCAPE b
{
    [self.queue addOperationWithBlock:b];
}

- ( void ) escape:( void (^)( NSString * ) ) b
{
    b ( @"away" );
    [self.queue waitUntilAllOperationsAreFinished];
}

(我希望在以前版本的编译器上对此进行测试以进行验证,但手头没有。)

enumerateObjectsUsingBlock: 的文档说

This method executes synchronously.

添加 NS_NOESCAPE 时文档未更新。