0

(在 iPhone Objective-C 中编程)

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

相关代码:

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

@synthesize shipAddr;

查看DID加载:

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

**在这里崩溃:

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

**

4

4 回答 4

2

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

您正在崩溃,因为stringByAppendingString:返回一个自动释放的字符串。因此,保留原件多少次都没关系;每次调用stringByAppendingString:(或任何其他stringByWhatever方法)时,都会得到一个生命周期有限的新字符串。

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

于 2009-07-14T00:28:10.613 回答
0

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

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

于 2009-07-14T00:25:25.417 回答
0

我假设您确实意识到该@synthesize语句位于实现文件中,而不是标题中。

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

self.shipAddr = @"";

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

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

NSLog(@"%@", shipAddr);

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

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

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

因为这使用了 shipAddr 的属性,正如您所定义的,它保留了传递的参数并解决了问题。

于 2009-07-14T00:28:26.183 回答
0

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

于 2009-07-14T00:28:37.057 回答