ios - 在 block 中引用 iOS 应用程序委托(delegate)是否会创建委托(delegate)对象的副本?

标签 ios objective-c macos

考虑以下示例:

- (void)exampleFunction
{
  AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  SomeClass *classObject = [[SomeClass alloc] init];
  [classObject someFunctionThatDoesBackgroundWorkAndCallsACompletionBlock:^(NSDictionary *results) {
    SomeNeatObject *object = appDelegate.someNeatObject;
    [object doSomeNeatStuff:results];
  }];
}

假设完成 block 在主/UI 线程上执行以避免额外的疯狂,这是我不确定的:

  1. 当在 block 内引用变量时,appDelegate 变量是否按照正常的 block 规则复制到堆栈上?
  2. 如果对 #1 的回答是肯定的,那么这是一种好的/安全的做法吗?如果您在随后分派(dispatch)到 GCD 队列的 block 中执行此操作,我认为这可能会导致问题,因为 .someNeatObject 可能已更改状态/变为 nil?

我意识到 appDelegate 不应该被过度使用,但如果您使用 Apple 的模板来初始化 Core Data 堆栈(at至少在 iOS 项目上)。那个特殊情况(核心数据)让我担心,因为该堆栈的大部分内容都不是线程安全的,复制它也不是一个好主意。

提前致谢。

最佳答案

您的示例将无法编译,因为未定义委托(delegate)。我假设你的意思是“SomeNeatObject *object = appDelegate.someNeatObject;”

在这个例子中,appDelegate 是一个变量,它的值将被 block 捕获。它与任何其他变量没有什么不同。

这并非不安全,因为 [[UIApplication sharedApplication] delegate] 总是返回相同的东西,除非您更改委托(delegate),而您可能不会这样做。

这里的基本概念是:appDelegate 是一个变量,它指向(或引用)一个对象 AppDelegate 类型的(或实例)。在 iOS 应用程序中有一个这样的实例,它由 [[UIApplication sharedApplication] delegate] 返回。如果您在 block 内创建对 appDelegate 的引用,则您正在复制变量,而不是对象。所以在你的代码块中:

SomeNeatObject *object = appDelegate.someNeatObject;

这在语义上与将以下代码放入 block 中相同(省略强制转换):

SomeNeatObject *object = [[UIApplication sharedApplication] delegate].someNeatObject;

被引用的 SomeNeatObjects 是同一件事。

稍微高级一点的概念:任何对象在内存中都有一个地址(一个整数,通常以十六进制形式出现)。如果两个变量具有相同的十六进制值,则它们指向同一个对象。如果它们具有不同的值,则它们指向不同的对象。在您的示例中,appDelegate(外部 block )和 appDelegate(内部 block )具有相同的值,因此指向相同的对象。

如果你要这样做:

AppDelegate * otherDelegate = [appDelegate copy];

然后您将复制 appDelegate 指向的对象。但请不要这样做。

关于ios - 在 block 中引用 iOS 应用程序委托(delegate)是否会创建委托(delegate)对象的副本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22826288/

相关文章:

objective-c - pkgbuild postinstall 脚本在其他人的 Mac 上导致 "Installation failed"

macos - Apache Tomcat 启动失败

c# - 自定义搜索图像 child 安全

ios - 实例化 View Controller 时出现类型不匹配错误

iOS MDM : push not working

ios - 使用 `textField:shouldChangeCharactersInRange:` ,如何获取包含当前键入字符的文本?

ios - vDSP 和 FFT 计算

ios - 用户允许共享并找到位置后继续处理

objective-c - 在 iOS 应用程序中存储常量的最佳位置在哪里?

c++ - 尝试在方法中包装 glGenVertexArrays 调用时出现段错误