2009-07-25 156 views
1

我遇到了一些NSString保留问题。我的问题是,在第二个函数(runItem)它似乎没有拿起item1的价值。无论我如何设定,它似乎只是设定为零。我是Cocoa的编程(桌面,与iPhone),我以前没有与NSString这种类型的问题。我不知道我在做什么来实现它,所以如果任何人都可以帮助我,我会非常感激!我在我的AppController.h文件代码:NSString保留问题

@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); 
} 

回答

5

嗯,虽然在第一个AppController对象设置item1,要创建一个AppController对象(直接,(由所述应用程序创建的,因为它是用NIB文件相关联的一个)通过默认“ init“构造函数),其item1从未设置。然后你要求第二个对象的item1,所以当然是nil

也许这是因为你认为awakeFromNib在对象初始化时被调用?但这完全不是事实。仅在加载NIB文件时创建的对象才会调用awakeFromNib

+1

这是正确的,虽然“awakeFromNib”中没有冒号。 – 2009-07-25 04:57:38

+0

newacct:这很有意义。我将它切换到[self runItem:self],现在它效果很好。谢谢你的帮助! – PF1 2009-07-25 15:53:16

1

你不保留它,因为你不是通过属性 - 你直接去分配到实例变量。使用self.item1 = [savedFile objectForKey:@"Item Title"]可以使用该属性的合成设置器来设置该值,该设置器将保留该设置器。

此外,您应该使用copy而不是retain,其值应符合NSCoding,尤其是当这些值可能是可变的时。字符串就是这样一种情况:你真的不想在变异的时候保持别人的可变字符串。你想制作自己的副本,以便不管其他对象如何处理字符串,字符串的值都是固定的。

+0

嗨,彼得:谢谢你的建议。我将来肯定会考虑到这一点。但是,对于这个问题,似乎不管我如何保留item1,它仍然不起作用。我将item1的所有实例都更改为“self.item1” - 但即使更改了它,它仍然不起作用。即使通过调用[item1 retain],它仍然拒绝保留。 – PF1 2009-07-25 04:52:13

0

需要更多的细节:

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

而且,简单地调用item1 = @"something"不会导致在你的@property声明中定义了它被保留,你需要调用self.item1 = @"something"对要使用的合成属性,否则你干脆直接设置指针。

+0

嗨昵称: 1.是的,awakeFromNib被调用,我再次用NSLog语句检查。 2.我相信我通过运行“if(savedFile!= nil)”来检查这一点,但我可能对此有错。 3.是的,该值存在于文件中。 此外,这对于self.item1部分是有意义的 - 但即使在添加之后,它仍然不起作用。另外,为了试用它,我调用了[item1 retain]来查看它是否会以这种方式工作,而事实并非如此。所以我在想,出于某种原因,不管你用哪种方式称呼它,它都不会保留。 – PF1 2009-07-25 04:49:32

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 =

此行的第二个问题与问题行为一样,不能保证savedFile字典中有关键字@"Item Title"的对象。如果没有,它将返回NULL

问题4:

item1 = nil; 

如果item1包含一个有效的指针到一个对象,你刚刚泄露了。你可能意思是self.item1 = nil;