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

时间:2010-07-29 10:20:02

标签: objective-c memory-management properties variable-assignment

我似乎无法通过iOS获得有关属性和内存管理的内容!

在我的AppDelegate中,我想要一个NSString *属性:

  • 我已经在.h文件中声明了这一点:

    @property(非原子,复制)NSString * myString;

  • 并在.m

  • 中将其合成

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

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

notificationDictionary是我NSDictionary*的{​​{1}}字典application:didFinishLaunchingWithOptions:中的launchOptions

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

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

为了100%确定发生了什么,我保留了我的属性多次并在每次访问时显示其保留计数的值:保留计数在我给一个值的方法之间的某处减少财产和我读它的方法。

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

1 个答案:

答案 0 :(得分:4)

这一行:

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

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

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

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

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

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