我真的对这个感到困惑。
这是我的代码:
for (SomeObject *obj in objects) {
[self checkAndDownloadForObjectbj];
}
- (void)checkAndDownloadForObjectid)obj
{
switch (obj.type) {
开关内部
... switch case scope
NSString *someId = [object.ID copy];
NSInteger random = arc4random();
NSLog(@"working on id=%@", someId);
void (^flock)(NSData *data, NSError *error) = ^(NSData *data, NSError *error) {
NSLog(@"downloaded image for %@ image =%p", someId, data);
NSLog(@"random = %u", random);
[self useDataForId:someId withData:data];
};
NSLog(@"flock %@", flock);
[downloader download:someUrl completionHandler:flock];
void (^aBlock)(int rand) = ^(int rand){
NSLog(@"block ra =%d random %u someId %@", rand, random, someId);
};
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
int ra = arc4random();
aBlock(ra);
});
// end of switch case scope
当我运行我在日志中看到的代码时:
2014-03-31 17:05:10.741 App[4142:60b] working on id=v7GhDlrq
2014-03-31 17:05:10.742 App[4142:60b] flock <__NSMallocBlock__: 0x17e86e00>
2014-03-31 17:05:10.787 App[4142:60b] working on id=tns_7Z-I
2014-03-31 17:05:10.788 App[4142:60b] flock <__NSMallocBlock__: 0x17ec85c0>
2014-03-31 17:05:10.824 App[4142:60b] downloaded image for v7GhDlrq image =0x18528a00
2014-03-31 17:05:10.825 App[4142:60b] random = 3993203783
2014-03-31 17:05:10.830 App[4142:60b] downloaded image for v7GhDlrq image =0x1852cc00
2014-03-31 17:05:10.831 App[4142:60b] random = 3993203783
2014-03-31 17:05:11.885 App[4142:60b] block ra =-2048013895 random 3993203783 someId v7GhDlrq
2014-03-31 17:05:11.886 App[4142:60b] block ra =513751079 random 727217709 someId tns_7Z-I
所以你可以看到 flock
block 应该捕获 someId
这在边界函数的不同调用中是不一样的,然后根据它执行一些事情。 aBlock
按预期工作,但 flock
始终使用相同的(第一个)someId
。我还放了一个随机数进行仔细检查,然后再次检查第一个值被复制并用于两个调用。
[downloader download:someUrl completionHandler:flock];
方法将flock复制到具有相同 block 类型的复制属性的对象,然后下载资源然后执行保存的 block 。
编辑1: 如果我传递 block 文字而不是先创建变量
[downloader download:someUrl completionHandler:^{
...block
}];
在调试器中,如果我设置断点,我可以看到该 block 是 _NSStackBlock_ 并且它具有相同的地址(即这是相同的 block 文字)在不同调用边界函数。这意味着我收到与完成处理程序相同的 block 副本,因此我打印相同的 someId
但在这种情况下出现了一个问题:为什么我收到相同的堆栈 block 文字???
能否请您指出这段代码有什么问题?或者为什么在我的情况下 block 的行为是这样的?
"Why do I receive the same stack block literal?"
你没有。
最初, block 是在堆栈上创建的。无论如何,当方法返回时,此“自动”变量将不复存在。但是,此堆栈 block 可能/将在 download:completionHandler:
中复制。由于循环,一个新的堆栈 block 很可能会获得相同的地址 - 但它与前一个不同,因为该堆栈 block 已被释放。
不过,您在日志中看到的内容似乎有点奇怪。我也相信,您应该看到 someId
的不同值。
在一个简单的测试用例中,我无法重现您的问题。我怀疑其他地方有问题。
关于ios - Objective-C block 。上下文捕获相同的变量/复制相同的 NSStackBlock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22766238/
欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://ogeek.cn/) | Powered by Discuz! X3.4 |