我似乎无法通过iOS获得有关属性和内存管理的内容!
在我的AppDelegate
中,我想要一个NSString *
属性:
我已经在.h
文件中声明了这一点:
@property(非原子,复制)NSString * myString;
并在.m
。
我的一个方法使用这样的属性:
myString = [notificationDictionary objectForKey:@"myKey"];
(notificationDictionary
是我NSDictionary*
的{{1}}字典application:didFinishLaunchingWithOptions:
中的launchOptions
我认为这意味着我的UIApplicationLaunchOptionsRemoteNotificationKey
拥有自己的AppDelegate
副本,保留计数为1,对吗?
然后另一个方法尝试访问该属性,但我得到myString
异常。
为了100%确定发生了什么,我保留了我的属性多次并在每次访问时显示其保留计数的值:保留计数在我给一个值的方法之间的某处减少财产和我读它的方法。
哪个对象将release方法发送到我的字符串?
答案 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异常。