首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在NSMutableString对象上调用stringWithString时崩溃

在NSMutableString对象上调用stringWithString时崩溃
EN

Stack Overflow用户
提问于 2011-03-02 19:28:00
回答 3查看 774关注 0票数 1

当用户单击“保存”按钮时,我运行以下代码:

代码语言:javascript
复制
- (IBAction) onSaveChangesClick:(id)sender  {

NSMutableString *newGroups = [[NSMutableString alloc] init];


for (int i = 0; i < [self.isInGroupArr count]; i++) {
    if ([[self.isInGroupArr objectAtIndex:i] boolValue] == YES) {
        [newGroups appendString:[[AppDelegate arrayGroups] objectAtIndex:i]];
        [newGroups appendString:@","];
    }
}

//  remove last : ","
if ([newGroups length] > 0)
    newGroups = [NSMutableString stringWithString:[newGroups substringToIndex:[newGroups length] - 1]];


self.contact.groups = newGroups;
[newGroups release];
//[[self navigationController] popViewControllerAnimated:YES];
}

self.IsInGroupsBOOL数组,arrayGroups是保存组名称的(NSString *) array。我想将newGroups字符串添加到arrayGroups[i] only if (IsInGroups[i] == YES)中。

这段代码生成EXC_BAD_ACCESS。为什么?

谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-03-02 19:40:30

在这里,您可以创建NSMutable字符串的自动发布实例。

代码语言:javascript
复制
newGroups = [NSMutableString stringWithString:[newGroups substringToIndex:[newGroups length] - 1]];

所以你不应该发布它,一切都会好起来的。

以下是改进后的代码:

代码语言:javascript
复制
- (IBAction) onSaveChangesClick:(id)sender  {

NSMutableString *newGroups = [[[NSMutableString alloc] init] autorelease];


for (int i = 0; i < [self.isInGroupArr count]; i++) {
    if ([[self.isInGroupArr objectAtIndex:i] boolValue] == YES) {
        [newGroups appendString:[[AppDelegate arrayGroups] objectAtIndex:i]];
        [newGroups appendString:@","];
    }
}

//  remove last : ","
if ([newGroups length] > 0)
    newGroups = [NSMutableString stringWithString:[newGroups substringToIndex:[newGroups length] - 1]];


self.contact.groups = newGroups;

//[[self navigationController] popViewControllerAnimated:YES];

}

解释:

  1. 在这里你可以分配并保留内存。

[ smth alloc init]

  • [NSMutableString stringWithString:返回我们不应该释放的NSMutable字符串的自动释放实例(它与[[NSMutableString alloc ] autorelease] +smth more相同)。并将其赋值给变量newGroups(因此存储在此变量中的旧值将丢失)

if (newGroups length > 0) newGroups = [NSMutableString stringWithString:[newGroups length - 1]];

这里的

  1. newGroups是自动释放的,你释放它,它就会销毁。但是当它被自动释放时,自动释放池再次尝试释放它,并得到异常(因为内存是空闲的)

newGroups版本;

票数 1
EN

Stack Overflow用户

发布于 2011-03-02 19:38:25

代码语言:javascript
复制
newGroups = [NSMutableString stringWithString:[newGroups substringToIndex:[newGroups length] - 1]];

这条线产生一个泄漏,然后就是崩溃的原因。

在此代码执行后,您将不再拥有对alloc/inited可变字符串的引用,而拥有一个自动释放的字符串。因此,在该字符串上调用release会导致某个地方的双重释放。

编辑:使用解决方案

最简单的解决方案:不要添加最后一个',‘。

代码语言:javascript
复制
for (int i = 0; i < [self.isInGroupArr count]; i++) {
    if ([[self.isInGroupArr objectAtIndex:i] boolValue] == YES) {
        [newGroups appendString:[[AppDelegate arrayGroups] objectAtIndex:i]];
        if (i != ([self.isInGroupArr count] - 1))
            [newGroups appendString:@","];
    }
}

不是很优雅,但很高效(但可以避免每次都要计数)。

票数 2
EN

Stack Overflow用户

发布于 2011-03-02 19:42:48

您已经分配了一个字符串(NSMutableString *newGroups = [NSMutableString alloc ];)

然后给它分配一个自动释放字符串(newGroups= [NSMutableString stringWithString:[newGroups stringWithString:[newGroups substringToIndex:newGroups length - 1]];)。

这是你永远不应该做的。请参阅此博客- http://andycodes.tumblr.com/post/947927280/difficult-bug-finally-solved

注释掉newGroups release;代码应该工作得很好。

此外,始终设置NSZombieEnabled环境变量并再次运行代码,查看崩溃日志,您将确切地了解是哪个对象导致了崩溃。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5166824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档