gpt4 book ai didi

objective-c - 按值或引用访问变量

转载 作者:太空狗 更新时间:2023-10-30 03:48:23 29 4
gpt4 key购买 nike

在下面的示例中,我不明白为什么 localVariable 是通过 doSomethingWithObject 中的值访问的。是什么导致了这种转变?如何区分按值访问变量和按引用访问变量?如果可能,我希望看到更多相关示例。

以下是 Apple 的 Blocks Programming Topics 的摘录并显示实例变量如何保留在 block 中。

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);
});

最佳答案

这是因为当您直接访问实例变量时,编译器(或多或少)会将其转换为结构成员查找。所以:

[ivar doSomething];

成为

[self->ivar doSomething];

因为需要self,所以必须保留self。但是,当您将指针值复制到新变量中时,您知道不再需要 self 结构来知道指针值是什么,因此 self 不需要保留,因为指针值可以从堆栈中复制 const。实例变量不会发生这种情况(因为在创建 block 和执行 block 之间,ivar 可能会发生变化)。


澄清:

  • block 必须保留它在内部引用的所有对象,以确保这些对象在 block 的生命周期内继续存在。
  • 当您直接在代码中访问 ivar 时,您实际上只是在查找结构的成员(因为 Objective-C 对象实际上只是结构)
  • 查找一个结构的成员意味着你必须拥有该结构
  • 因此, block 将保留结构(在本例中为 self),以便查找始终成功。如果它不这样做,那么 self 将来可能会被释放,现在结构查找会导致错误访问(很可能)并且您的应用程序会崩溃。
  • 或者,您可以在当前堆栈帧中本地创建一个新的对象指针。这样做的好处是您不再需要保留 self,因为 self 不再参与检索相关对象的地址
  • 当然,局部变量引用的对象将被保留,以确保它在 block 的生命周期内存在。
  • 在此处使用术语“按值”和“按引用”是完全不正确的。 Objective-C 中的对象总是通过引用传递,因为我们总是传递指针。您不能在 Objective-C 中按值传递对象。 (对此有一些注意事项,但您真的不想去那里)有关按值传递与按引用传递的含义的更多信息,请查看以下问题:What's the difference between passing by reference vs. passing by value?

关于objective-c - 按值或引用访问变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6433348/

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