类变量可在一个函数的末尾访问,并在下一个开始时访问时崩溃

时间:2009-07-14 00:20:41

标签: iphone uitableview nsstring

(在iPhone目标C中编程)

我有一个类级NSString *我创建,添加属性(非原子,保留)和合成代码,我可以使用stringByAppendingString函数无限地修改字符串,并使用NSLog显示字符串就好了。所有这些都是在子类中完成的,重写了viewDidLoad函数。当我在确定在tableView的单元格中显示什么时尝试从cellForRowAtIndexPath函数访问相同的变量时,程序崩溃。有人有任何线索吗?

相关代码:

@interface InfoViewController : UITableViewController {
    NSString *shipAddr;
}
@property (nonatomic,retain) NSString *shipAddr;

@synthesize shipAddr;

viewDidLoad中:

shipAddr = [[[NSString alloc] initWithString:@""] retain];

**在这里崩溃:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(shipAddr);

**

4 个答案:

答案 0 :(得分:2)

你实际上是双重保留原始字符串,这会泄漏它,但这不是导致崩溃的原因。

你崩溃是因为stringByAppendingString:返回一个自动释放的字符串。因此保留原件的次数并不重要;每次调用stringByAppendingString:(或任何其他stringByWhatever方法)时,您都会获得一个生命周期有限的新字符串。

对于您的代码,我建议您始终只分配给self.shipAddr,并将@""分配给字符串开头。 self.shipAddr版本将自动为您处理内存管理。

答案 1 :(得分:0)

尝试在viewDidLoad和tableView:cellForRowAtIndexPath:方法的开头放置一个NSLog语句。如果后者首先运行,那么它将在创建变量之前尝试访问该变量。

如果您知道shipAddr应该足够早,我会将初始化放在您的init方法中。

答案 2 :(得分:0)

我假设你确实意识到@synthesize语句在实现文件而不是标题中。

同样在viewDidLoad,如果你必须这样做,我认为你可以这样做:

self.shipAddr = @"";

由于已定义属性以保留传递的参数。

我注意到的最后一件事是,我相信对NSLog的调用应该是这样的:

NSLog(@"%@", shipAddr);

函数的格式如下:void NSLog(NSString *format, ...);

是的,正如布伦特所提到的那样,因为stringByAppendingFormat返回一个自动释放的字符串,它可能会“消失”,然后才能在其他方法中看到它。所以你应该使用它:

self.shipAddr = [shipAddr stringByAppendingFormat: blah blah];

因为它使用了shipAddr的属性,正如您所定义的那样,它保留传递的参数并处理问题。

答案 3 :(得分:0)

你确定在tableView之前调用了viewDidLoad:cellForRowAtIndexPath :?听起来字符串未初始化或在该函数中引用时释放。鉴于你在viewDidLoad中分配和保留字符串(你实际上不需要保留),我会说它还没有被初始化!