Objective c NSString意外变为uu NSCFDictionary

Objective c NSString意外变为uu NSCFDictionary,objective-c,iphone,nsstring,core-data,Objective C,Iphone,Nsstring,Core Data,我有一个非常奇怪的问题,我是objective-c的新手,它可能来自我还不了解的深处 因此,在我的头文件中,我声明了变量 NSString *curTitle; 然后在.m文件中,我将其合成: curTitle = [[NSString alloc] init]; 之后,在其他方法中,我指定: curTitle = string; // string is an instance of NSString 在一天结束的时候,当我试图分配 slide.title = curTitle; //s

我有一个非常奇怪的问题,我是objective-c的新手,它可能来自我还不了解的深处

因此,在我的头文件中,我声明了变量

NSString *curTitle;
然后在.m文件中,我将其合成:

curTitle = [[NSString alloc] init];
之后,在其他方法中,我指定:

curTitle = string; // string is an instance of NSString
在一天结束的时候,当我试图分配

slide.title = curTitle; //slide is a managed object (CoreData)
我收到此错误:**由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“属性的值类型不可接受:property=“title”;所需类型=NSString;给定类型=uu NSCFDictionary;值={ }.'

有趣的事实是,在iPhoneSDK3.2中它可以工作,但在我安装了SDK4之后,我出现了这个错误

另一个有趣的事实是,如果让我的类的curTitle属性(使用@property和@synthesis)也可以工作

有什么想法吗?
感谢

当一个对象似乎改变了类时,几乎总是因为它已被释放,而另一个对象现在驻留在同一内存位置。所有对象变量实际上都是指向内存位置的指针(这就是*的意思),并且与许多其他语言不同,您必须始终记住您正在使用内存位置。(好吧,不总是,一旦你掌握了窍门。但肯定是在你调试的时候。)

要调试这些问题,使用
NSZombie
非常有用。只需搜索SO或网络上的信息

然后在.m文件中,我将其合成:
curTitle=[[NSString alloc]init]

这是而不是。这里所做的只是给变量赋值。更准确地说,您可以在内存中的某个位置创建一个对象(alloc)并初始化它(init),然后将
curTitle
的值设置为指向该内存位置

您根本不需要在代码中包含这一行

curTitle=string

在这里,您将使用指向另一个字符串的指针覆盖
curTitle
的旧值。您的问题很可能是其他字符串后来被释放,内存位置被重新使用以保存另一个对象(本例中是字典)。(如果您不了解保留/释放机制,则需要阅读这些机制以了解发生了什么。)

slide.title=curTitle

由于
curTitle
指向一个内存位置,该内存位置已被重新用于保存一个随机对象(甚至更糟:垃圾),因此此行将失败。事实上,你很幸运它失败了,因为如果它没有(如果这个位置还没有被重用的话)它将更难检测到这个bug

您应该做的是声明一个属性,然后合成它,并通过该属性访问变量:

self.curTitle=aString


这将确保您实际复制并拥有字符串的所有权,这样即使原始字符串被释放,您仍将拥有一个有效的副本。

当一个对象似乎改变了类时,几乎总是因为它已被释放,而另一个对象现在驻留在同一内存位置。所有对象变量实际上都是指向内存位置的指针(这就是*的意思),并且与许多其他语言不同,您必须始终记住您正在使用内存位置。(好吧,不总是,一旦你掌握了窍门。但肯定是在你调试的时候。)

要调试这些问题,使用
NSZombie
非常有用。只需搜索SO或网络上的信息

然后在.m文件中,我将其合成:
curTitle=[[NSString alloc]init]

这是而不是。这里所做的只是给变量赋值。更准确地说,您可以在内存中的某个位置创建一个对象(alloc)并初始化它(init),然后将
curTitle
的值设置为指向该内存位置

您根本不需要在代码中包含这一行

curTitle=string

在这里,您将使用指向另一个字符串的指针覆盖
curTitle
的旧值。您的问题很可能是其他字符串后来被释放,内存位置被重新使用以保存另一个对象(本例中是字典)。(如果您不了解保留/释放机制,则需要阅读这些机制以了解发生了什么。)

slide.title=curTitle

由于
curTitle
指向一个内存位置,该内存位置已被重新用于保存一个随机对象(甚至更糟:垃圾),因此此行将失败。事实上,你很幸运它失败了,因为如果它没有(如果这个位置还没有被重用的话)它将更难检测到这个bug

您应该做的是声明一个属性,然后合成它,并通过该属性访问变量:

self.curTitle=aString


这将确保您实际复制并拥有该字符串的所有权,这样即使原始字符串被释放,您仍将拥有一个有效的副本。

再次检查您的代码。这种事情经常发生在我身上,这都是我的错。检查所有对Curtile的分配。再次检查您的代码。这种事情经常发生在我身上,这都是我的错。检查所有对curTitle的分配。非常感谢Felixyz的回答。你是对的,我的'string'变量被释放,所以我通过更改curTitle=string解决了它;使用curTitle=[string copy];你能给我解释一下或者给我一些参考资料,我什么时候应该使用,什么时候不应该使用?真的非常感谢,感谢您的帮助)@Aristarh:curTitle=[string copy];问题是,现在您有一个保留的字符串副本,如果以后不释放它,就会出现内存泄漏。这就是为什么理解内存处理规则至关重要的原因:关于内存处理规则有很多信息,所以:是的,我理解