• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - Objective-C block 。上下文捕获相同的变量/复制相同的 NSStackBlock

[复制链接]
菜鸟教程小白 发表于 2022-12-12 09:05:58 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我真的对这个感到困惑。

这是我的代码:

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 的行为是这样的?



Best Answer-推荐答案


"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/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap