(在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);
**
答案 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中分配和保留字符串(你实际上不需要保留),我会说它还没有被初始化!