哪个对象确实向我的财产发送了“释放”消息?

问题描述 投票:1回答:1

有一些我似乎没有得到iOS的属性和内存管理!

在我的AppDelegate,我想要一个NSString *财产:

  • 我在.h文件中以这种方式声明: @property(非原子,复制)NSString * myString;
  • 并在.m合成它。

我的一个方法使用这样的属性:

myString = [notificationDictionary objectForKey:@"myKey"];

notificationDictionaryNSDictionary*,我在application:didFinishLaunchingWithOptions:launchOptions字典中获得了关键的UIApplicationLaunchOptionsRemoteNotificationKey

我认为这意味着我的AppDelegate拥有自己的myString副本,保留计数为1,对吧?

然后另一种方法尝试访问该属性,但我得到一个EXC_BAD_ACCESS异常。

为了100%确定发生了什么,我多次保留我的属性并在每次访问时显示其保留计数的值:保留计数在我给我的属性赋值的方法和我读它的方法。

哪个对象将release方法发送到我的字符串?

objective-c memory-management properties variable-assignment
1个回答
4
投票

这一行:

myString = [notificationDictionary objectForKey:@"myKey"];

不使用您的综合属性访问器。它只是直接设置实例变量,并绕过自动复制行为。

为了使用您的属性访问器,您需要添加self.,如下所示:

self.myString = [notificationDictionary objectForKey:@"myKey"];

更新:我在这里更详细地回答了类似的问题:why-does-this-property-need-the-retain?

更新#2:为了进一步解释,向你的myString变量发送释放消息的“神秘对象”实际上是NSAutoreleasePool的一个实例,很可能是与你的主线程相关联的池。 [notificationDictionary objectForKey:...]返回的值是自动释放的,因此当您将此值分配给myString时,它将持续到当前运行循环结束。当运行循环结束时,它会耗尽自动释放池,将release发送到任何已标记为自动释放的对象。在发生这种情况之后,myString中的指针值引用了已释放的内存块。这种类型的死指针通常称为僵尸。当您尝试向僵尸发送消息时,通常会发生EXC_BAD_ACCESS异常。

© www.soinside.com 2019 - 2024. All rights reserved.