你怎么知道 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。他们只是列出了方法。
然后我尝试搜索 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
时文档未更新。
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。他们只是列出了方法。
然后我尝试搜索 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
时文档未更新。