我在NSString保留方面遇到了一些问题。我的问题是在第二个函数(runItem)上它似乎没有获取item1的值。不管我把它设置为什么,它似乎只是设置为零。我正在为Cocoa编程(桌面版,而不是iPhone版),之前我没有遇到过NSString这类问题。我不知道我在做什么导致它,所以如果有人能帮助我,我会非常感激!我的AppController.h文件中的代码:
@interface AppController : NSObject {
NSString *item1;
}
@property (retain) NSString *item1;
- (IBAction)runItem:(id)sender;
@end
和AppController.m:
@synthesize item1;
- (void)awakeFromNib: {
NSDictionary *savedFile = [NSDictionary dictionaryWithContentsOfFile:@"Users/me/Desktop/Testing.plist"];
if (savedFile != nil) {
item1 = [savedFile objectForKey:@"Item Title"];
AppController *runFunction = [[AppController alloc] init];
[runFunction runItem:self];
}
else {
item1 = nil;
}
}
- (IBAction)runItem:(id)sender
NSLog(@"%@", item1);
}
答案 0 :(得分:5)
嗯,虽然您在第一个item1
对象(由应用程序创建的对象,因为它与NIB文件关联)中设置了AppController
,但您创建的是 second < / em> AppController
对象(直接通过默认的“init”构造函数),其item1
从未设置过。然后你要求第二个对象是item1
,所以当然是nil
。
也许这是因为您认为只要对象初始化就会调用awakeFromNib
?但这完全不正确。仅对加载NIB文件时创建的对象调用awakeFromNib
。
答案 1 :(得分:2)
问题#1:在您提供的示例中,您有以下内容:
- (void)awakeFromNib: {
NSNibAwaking
协议仅定义awakeFromNib
。 非常 重要的是要注意最后没有冒号。如果你的代码中的这个方法实际上被调用了,那么它可能是由于一些内部的怪异而不是你应该依赖的东西(除非你能找到它记录在哪里,我不能)。我对文档的快速扫描表明,awakeFromNib
是唯一将被调用的选择器。
问题#2:
NSDictionary *savedFile = [NSDictionary dictionaryWithContentsOfFile:@"Users/me/Desktop/Testing.plist"];
我很确定你真正的意思是/Users
,而不是Users
。这可能意味着savedFile
始终为NULL
,因为它永远不会加载,因此以下if()
检查将始终使用else
条件。
问题#3:
item1 = [savedFile objectForKey:@"Item Title"];
如果您不使用GC,则此行是一个问题,因为从字典savedFile
检索到的对象尚未保留。此外,如果item1
包含指向对象的有效指针,则只需通过直接覆盖它来泄露它。你的意思可能是self.item1 =
。
此行的第二个问题是wrt /问题行为,即无法保证savedFile
字典具有键@"Item Title"
的对象。如果没有,则返回NULL
。
问题#4:
item1 = nil;
如果item1
包含指向对象的有效指针,则只是泄漏了它。你的意思可能是self.item1 = nil;
。
答案 2 :(得分:1)
您没有保留它,因为您没有通过该属性 - 您直接分配给实例变量。使用self.item1 = [savedFile objectForKey:@"Item Title"]
使用属性的合成setter设置值,该setter将保留它。
此外,对于值为copy
的属性,您应该使用retain
,而不是NSCoding
,尤其是当这些值可能是可变的时。字符串是这样的情况:你真的不想在他们变异时抓住别人的可变字符串。你想制作自己的副本,这样你的字符串的值就会保持不变,无论另一个对象的字符串是什么。
答案 3 :(得分:0)
需要更多详情:
另外,简单地调用item1 = @"something"
不会导致它被@property语句中定义的保留,您需要调用self.item1 = @"something"
来使用合成属性,否则您只需设置直接指针。