gpt4 book ai didi

ios - 对 Apple 的 Block Docs 的澄清?

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:09:18 24 4
gpt4 key购买 nike

我正在处理 block /ARC 的一些保留周期问题,我正在努力了解其中的细微差别。任何指导表示赞赏。

Apple 关于“ block 和变量”的文档 (http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html) 说明如下:

If you use a block within the implementation of a method, the rules for memory management of object instance variables are more subtle:

If you access an instance variable by reference, self is retained; If you access an instance variable by value, the variable is retained. The following examples illustrate the two different situations:

dispatch_async(queue, ^{
// instanceVariable is used by reference, self is retained
doSomethingWithObject(instanceVariable);
});


id localVariable = instanceVariable;
dispatch_async(queue, ^{
// localVariable is used by value, localVariable is retained (not self)
doSomethingWithObject(localVariable);
});

我觉得这个解释很困惑。

  1. “按值”/“按引用”术语的使用是否恰当?假设这些变量属于同一类型 (id),那么它们之间的区别特征似乎就是它们的作用域。
  2. 我没有看到“通过引用”示例中如何引用 self?如果正在使用访问器方法(例如 - 下面),我可以看到 self 被保留。

    doSomethingWithObject(self.instanceVariable);

  3. 对于何时可能希望以一种或另一种方式做事,您有任何指导吗?

  4. 如果传统智慧是利用“按值”变量,这似乎会导致大量额外的代码用于额外的变量声明?
  5. 在嵌套 block 开始发挥作用的情况下,避免在彼此内部声明 block 似乎更易于维护,因为最终可能会以一堆无意保留的对象而告终?

最佳答案

将使用 instanceVariable 的情况视为等同于编写 self->instanceVariable。实例变量根据定义“附加”到 self 对象,并在 self 对象存在时存在。

使用instanceVariable(或self->instanceVariable)意味着你从self的地址开始,并要求一个实例变量(即一些字节的偏移量) self 对象的原始地址)。

使用 localVariable 本身就是一个变量,不依赖于自身,也不是相对于另一个对象的地址。

由于 block 在创建时会捕获变量,因此当您的意思是“当 block 被执行时,我想在执行时获取实例变量的值”时,您通常更喜欢使用实例变量,因为您会此时向 self 对象询问实例变量的值(与调用 [self someIVarAccessorMethod] 的方式完全相同)。但是请注意不要创建一些保留循环。

另一方面,如果你使用localVariable,局部变量(而不是self)将在创建 block 时被捕获,所以即使局部变量 block 创建后更改,旧值将在 block 内使用。

// Imagine instanceVariable being an ivar of type NSString
// And property being a @property of type NSString too
instanceVariable = @"ivar-before";
self.property = @"prop-before";
NSString* localVariable = @"locvar-before";

// When creating the block, self will be retained both because the block uses instanceVariable and self.property
// And localVariable will be retained too as it is used directly
dispatch_block_t block = ^{
NSLog(@"instance variable = %@", instanceVariable);
NSLog(@"property = %@", self.property);
NSLog(@"local variable = %@", localVariable);
};

// Modify some values after the block creation but before execution
instanceVariable = @"ivar-after";
self.property = @"prop-after";
localVariable = @"locvar-after";

// Execute the block
block();

在该示例中,输出将显示 instanceVariableself.property 是通过 self 对象访问的,因此保留了 self 但instanceVariableself.property 的值在 block 的代码中被查询,它们将在执行时返回它们的值,分别为 "ivar-after"“prop-after”。另一方面,localVariable 在创建 block 时被保留,并且它的值在那时被常量复制,所以最后的 NSLog 将显示 "locvar-before”.

self 在 block 的代码中使用实例变量或属性或调用 self 本身的方法时被保留。当您在 block 的代码中直接使用局部变量时,它们会被保留。

注意:我建议您观看讨论该主题的 WWDC'11 和 WWDC'12 视频,它们确实很有启发性。

关于ios - 对 Apple 的 Block Docs 的澄清?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12287696/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com