NSString保留问题

时间:2009-07-25 03:57:29

标签: cocoa memory-management

我在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);
}

4 个答案:

答案 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)

需要更多详情:

  • 你知道正在调用awakeFromNib吗?
  • 你知道savedFile是非零吗?
  • 您知道savedFile中的“Item Title”是否存在且非零?

另外,简单地调用item1 = @"something"不会导致它被@property语句中定义的保留,您需要调用self.item1 = @"something"来使用合成属性,否则您只需设置直接指针。