菜鸟教程小白 发表于 2022-12-12 09:05:58

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


                                            <p><p>我真的对这个感到困惑。</p>

<p>这是我的代码:</p>

<pre><code>for (SomeObject *obj in objects) {
    ;
}

- (void)checkAndDownloadForObject:(id)obj
{
    switch (obj.type) {
</code></pre>

<p>开关内部</p>

<pre><code>... switch case scope

NSString *someId = ;   
NSInteger random = arc4random();
NSLog(@&#34;working on id=%@&#34;, someId);

void (^flock)(NSData *data, NSError *error) = ^(NSData *data, NSError *error) {
    NSLog(@&#34;downloaded image for %@ image =%p&#34;, someId, data);
    NSLog(@&#34;random = %u&#34;, random);
    ;                  
};

NSLog(@&#34;flock %@&#34;, flock);

;

void (^aBlock)(int rand) = ^(int rand){
    NSLog(@&#34;block ra =%d random %u someId %@&#34;, 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
</code></pre>

<p>当我运行我在日志中看到的代码时:</p>

<pre><code>2014-03-31 17:05:10.741 App working on id=v7GhDlrq
2014-03-31 17:05:10.742 App flock &lt;__NSMallocBlock__: 0x17e86e00&gt;
2014-03-31 17:05:10.787 App working on id=tns_7Z-I
2014-03-31 17:05:10.788 App flock &lt;__NSMallocBlock__: 0x17ec85c0&gt;
2014-03-31 17:05:10.824 App downloaded image for v7GhDlrq image =0x18528a00
2014-03-31 17:05:10.825 App random = 3993203783
2014-03-31 17:05:10.830 App downloaded image for v7GhDlrq image =0x1852cc00
2014-03-31 17:05:10.831 App random = 3993203783
2014-03-31 17:05:11.885 App block ra =-2048013895 random 3993203783 someId v7GhDlrq
2014-03-31 17:05:11.886 App block ra =513751079 random 727217709 someId tns_7Z-I
</code></pre>

<p>所以你可以看到 <code>flock</code>block 应该捕获 <code>someId</code> 这在边界函数的不同调用中是不一样的,然后根据它执行一些事情。 <code>aBlock</code> 按预期工作,但 <code>flock</code> 始终使用相同的(第一个)<code>someId</code>。我还放了一个随机数进行仔细检查,然后再次检查第一个值被复制并用于两个调用。</p>

<pre><code>;
</code></pre>

<p>方法将flock复制到具有相同 block 类型的复制属性的对象,然后下载资源然后执行保存的 block 。</p>

<p>编辑1:
如果我传递 block 文字而不是先创建变量</p>

<pre><code> [downloader download:someUrl completionHandler:^{
      ...block
}];
</code></pre>

<p>在调试器中,如果我设置断点,我可以看到该 block 是 <strong>_<em>NSStackBlock</em>_</strong> 并且它具有相同的地址(即这是相同的 block 文字)在不同调用边界函数。这意味着我收到与完成处理程序相同的 block 副本,因此我打印相同的 <code>someId</code> 但在这种情况下出现了一个问题:为什么我收到相同的堆栈 block 文字???</p>

<p>能否请您指出这段代码有什么问题?或者为什么在我的情况下 block 的行为是这样的?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><blockquote>
<p>&#34;Why do I receive the same stack block literal?&#34;</p>
</blockquote>

<p>你没有。 </p>

<p>最初, block 是在堆栈上创建的。无论如何,当方法返回时,此“自动”变量将不复存在。但是,此堆栈 block 可能/将在 <code>download:completionHandler:</code> 中复制。由于循环,一个新的堆栈 block 很可能会获得相同的地址 - 但它与前一个不同,因为该堆栈 block 已被释放。 </p>

<p>不过,您在日志中看到的内容似乎有点奇怪。我也相信,您应该看到 <code>someId</code> 的不同值。 </p>

<p>在一个简单的测试用例中,我无法重现您的问题。我怀疑其他地方有问题。 </p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - Objective-Cblock 。上下文捕获相同的变量/复制相同的 NSStackBlock,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/22766238/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/22766238/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - Objective-C block 。上下文捕获相同的变量/复制相同的 NSStackBlock