Objective c NSString EXC\u访问错误

Objective c NSString EXC\u访问错误,objective-c,exc-bad-access,Objective C,Exc Bad Access,我被下面的代码卡住了 NSString *gridRef = [[NSString alloc] initWithFormat: @"%@", [converter LatLongToOSGrid: latLong]]; NSLog(@"Grid Ref: %@", gridRef); self.answerLabel.text = [[NSString alloc] initWithFormat: @"%@", gridRef]; 当我记录gridRef时,它会显示正确的结果。但是,行设置a

我被下面的代码卡住了

NSString *gridRef = [[NSString alloc] initWithFormat: @"%@", [converter LatLongToOSGrid: latLong]];
NSLog(@"Grid Ref: %@", gridRef);
self.answerLabel.text = [[NSString alloc] initWithFormat: @"%@", gridRef];
当我记录gridRef时,它会显示正确的结果。但是,行设置answerLabel.text会导致EXC_BAD_访问错误,程序会崩溃。IB连接到正确的标签,有什么问题

谢谢


我已将代码更新如下:

    - (IBAction)convertLatLong {
    NSArray *latLong = [[NSArray alloc] initWithObjects: latTextField.text, longTextField.text, nil];

    GridRefsConverter *converter = [[GridRefsConverter alloc] init];

    NSString *gridRef = [[NSString alloc] initWithFormat: @"%@", [converter LatLongToOSGrid: latLong]];
    NSLog(@"Grid Ref: %@", gridRef);
    NSLog(@"Label: %@", self.answerLabel.text);
    answerLabel.text = @"Yippy";
    self.answerLabel.text = gridRef;

    [gridRef release];
    [converter release];
    [latLong release];
}
当视图控制器被推到堆栈上时,answerLabel通过@property@Synthesis初始化。(我不知道它是如何初始化的,除了它是IB为你做的一件神奇的事情。或者我这么认为。我在其他视图控制器中使用了完全相同的方法,没有这个问题


我找到了罪犯——问题是,我该如何释放他们

NSString *eString = [[NSString alloc] initWithFormat: @"%f", e];
NSString *nString = [[NSString alloc] initWithFormat: @"%f", n];
eString = [eString stringByPaddingToLength: (digits/2) withString: @"0" startingAtIndex: 0];
nString = [nString stringByPaddingToLength: (digits/2) withString: @"0" startingAtIndex: 0];
NSString *theGridRef = [letterPair stringByAppendingString: eString];
theGridRef = [theGridRef stringByAppendingString: nString];
[eString release];
[nString release];

return theGridRef;
以及:


}

检查
asnwerLabel
是否实际为非空。您还应更改此行:

self.answerLabel.text = [[NSString alloc] initWithFormat: @"%@", gridRef];
致:


否则,您将导致该行内存泄漏。

可能标签未在代码中的该点初始化,请尝试检查它。为什么要分配新的NSString? 只要做:


answerLabel是如何创建的?您可能需要保留它。或者您可能需要发布一些东西(gridRef)

我看不出你的代码还有其他问题

你可以(也可能应该)设置你的

answerLabel.text = gridRef;
gridRef已经是一个NSString,因此不需要再次分配它


EXC_BAD_访问通常是与保留/释放计数不平衡相关的内存问题(或在我的广泛经验中:p)。

您应该通过将环境变量
NSZombieEnabled
设置为YES来启用僵尸检测,这样您就可以看到是哪个对象导致了错误访问(当你发现bug时,别忘了再次删除它)

您还可以使用仪器查找对象实际释放的位置。为此,请启动新的仪器会话并使用“分配”仪器。在仪器设置中,选中“启用NSZombie检测”和“记录引用计数”。运行会话时,您将在发生错误的位置中断,并看到所有保留/释放的记录

如果对象被错误释放,可以在-viewDidUnload方法中快速查看。在该方法中,您应该释放outlet并将其设置为nil。如果您忘记了后者,并以某种方式访问outlet,则会导致EXC\u BAD\u访问

编辑以匹配您的更新:

问题是您正在为eString(和nString)分配一个alloc/init-ed的新字符串。然后您将在下一个语句中重写这些字符串,因为
-stringByPaddingToLength:
(以及所有其他
-stringBy…
方法)返回一个新的自动释放字符串对象。因此,您丢失了对旧字符串的引用,这意味着内存泄漏。此外,在结束时,您明确释放了已自动释放的对象,这会导致您的访问错误


相反,您应该从一开始就创建自动释放的字符串([NSString stringWithFormat:…]),不要在最后释放它们。

好的,问题是试图释放NSStrings,所以我停止了这一操作,问题已经解决

有人能澄清字符串是如何保留和释放的吗?我的印象是:

string=@“我的字符串”
自动删除。
NSString*string=[[NSString alloc]init…];
不是自动删除的,需要手动完成。

我已将代码更改为以下内容:NSString*gridRef=[[NSString alloc]initWithFormat:@“%@”[converter LatLongToOSGrid:latLong]];NSLog(@“Grid Ref:%@”,gridRef);NSLog(@“Label:%@),self.answerLabel.text);self.answerLabel.text=gridRef;NSLog输出为:2010-08-28 13:38:30.078 iFly[19777:207]网格参考:ST55102321 2010-08-28 13:38:30.079 iFly[19777:207]标签:标签程序收到信号:“EXC_坏访问”。由于标签未分配,因此似乎未打印。您使用哪种方法调用这段代码?如果您是在viewController的init方法中执行此操作,请尝试在标签更新后在
viewDidLoad
中执行此操作,而不是在释放GridRef时执行。我已仔细查看,看不到有关释放/r的任何问题etaining。如果NSLog正确输出它们,它们的保留计数肯定至少为1?是的,但是answerLabel呢?在更改其值NSLog(@“%@”,answerLabel.text)之前,给它一个值;并查看输出是否有任何内容…我正在与仪器进行斗争-如何设置它,以及输出的含义是什么?控制台,启用NSZombieEnabled告诉我-[CFString release]:消息已发送到已解除分配的实例0x68809e0。但我如何找出已解除分配的实例?在这里解释仪器将是一项艰巨的任务。不过,在此之前,有一个问题应该让您开始:谢谢,这为我澄清了很多事情。我正在慢慢了解ob中的整个内存管理jC.干杯!当我能帮助你时,你总是很高兴。如果你还没有这样做,我建议你阅读内存管理编程指南(),它详细解释了这些主题。@Fönsi你的答案帮助我..从最后发布时发生的错误中..谢谢
self.answerLabel.text = [NSString stringWithFormat: @"%@", gridRef];
self.label.text = gridRef;
[gridRef release];
answerLabel.text = gridRef;