我按以下方式创建NSMutable数组:
-(NSArray*)createArrayFromString:(NSString*)str
{
NSArray *arr = [str componentsSeparatedByString:@" "];
NSMutableArray *result = [NSMutableArray arrayWithCapacity:[arr count]];
for(NSString *s in arr){
if([s length]>0){
[result addObject:[s retain]];
}
}
return (NSArray*) result;
}
这里是调用方法,它将接收到的数组元素放入Chapter对象的属性resRefs中:
-(Chapter*)createChapter:(CXMLNode*)node
{
Chapter *chapter = [[Chapter alloc] init];
chapter._id = [[(CXMLElement*)node attributeForName:@"id"] stringValue];
chapter.title = [[(CXMLElement*)node attributeForName:@"title"] stringValue];
chapter.text = [node stringValue];
[chapter.pids addObjectsFromArray:[self createArrayFromString:[[(CXMLElement*)node attributeForName:@"pids"]stringValue]]];
[chapter.resRefs addObjectsFromArray:[self createArrayFromString:[[(CXMLElement*)node attributeForName:@"resRefs"]stringValue]]];
return chapter;
}
以下是问题:
没有
中的保留调用[result addObject:[s retain]];
我无法从ViewController访问NSString元素(EXC_BAD_ACCESS)
我是否正确使用保留在这里?
修改
已更改
[[result addObject:s] retain];
到
[result addObject:[s retain]];
第二行最初是在我的代码中。 发布此问题后删除保留并将其重新插入错误的位置。 尽管如此,保留在这里是有效的,而将它留下来并不是没有。
编辑2:
发现了分析仪(CMD + SHIFT + B),发现了几个内存泄漏, 删除它们,EXC_BAD_ACCESS消失了。 感谢各位的帮助!
答案 0 :(得分:8)
[result addObject:s]
什么都不返回,所以没有什么可以保留的。
对象被数组保留。
NSMutableArray *result = [NSMutableArray arrayWithCapacity:[arr count]];
不会被保留,也不应该保留,因为它是本地对象。
您应该熟悉memory rules。命名约定说,名称以“alloc”,“new”,“copy”或“mutableCopy”开头的方法必须提供一个retaind对象。所以你的方法似乎没问题,因为它不会从任何一个开始,并返回一个自动释放(=未保留)的对象。这是打电话的责任,保留与否。
还附注:
return (NSArray*) result;
不会将您的NSMutableArray转换为NSArray。演员表只告诉编译器它应该期待什么。由于NSMutableArray是一个NSArray,编译器已经知道了。实际上,转换已经由方法签名中的返回定义定义。
你在方法中做了些什么吗?如果不是 - 我不想让你感到苦恼 - 你真的不需要它,因为NSArray *arr = [str componentsSeparatedByString:@" "];
只是做你想要的。如果您确实希望@" "
远离来电者,则应考虑在NSString
componentsSeparatedByBlank
上使用名为@interface NSString (Separation)
-(NSArray *)componentsSeparatedByBlank;
@end
@implementation NSString (Separation)
-(NSArray *)componentsSeparatedByBlank
{
return [self componentsSeparatedByString:@" "];
}
@end
的{{1}}。
它可能看起来像
-(NSArray *)componentsSeparatedByWhiteSpace
{
NSArray *array = [self componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceCharacterSet]];
return [array filteredArrayUsingPredicate: [NSPredicate predicateWithFormat:@"SELF != ''"]];
}
或使用空格字符集:
{{1}}
答案 1 :(得分:3)
我是否正确使用保留在这里?
没有。 NSMutableArray保留您添加到其中的对象。然后,当您调用remove或数组被dealloc'd时,它会释放它们。您无需在此处致电保留。但是,这不是您遇到EXC_BAD_ACCESS
的原因正如vikingosegundo所说,addObject不会返回任何内容,因此在其上调用retain会为您提供EXC_BAD_ACCESS。
您尝试执行的操作的正确语法是(注意:如上所述,无需执行此操作)
[result addObject:[s retain]]; // BAD
所以,总之,只是
[result addObject:s]; // GOOD - s is retained by result
编辑*改写海报原始代码......
-(NSArray*)arrayFromString:(NSString*)str // Note naming convention of method
{
NSMutableArray *arr = [str componentsSeparatedByString:@" "]; // Won't give you any 0 length strings
// Do some other character/validation checks here?
return arr; // returns autoreleased NSMutableArray complying to naming convention
}
如果您在返回之前不想对字符串执行任何操作,则可以在createChapters方法中使用它...
NSArray *arr = [[[(CXMLElement*)node attributeForName:@"pids"] stringValue] componentsSeparatedByString:@" "];
[chapter.pids addObjectsFromArray:arr];
请阅读内存管理和命名约定,将来会为您节省大量时间。
答案 2 :(得分:2)
[[result addObject:s] retain];
是一种无效方法。这意味着它不会返回任何值,如:
- (NSString)methodThatReturnsString;
会。你保留了一个空洞,它没有保留任何东西,因为虚空基本上没有任何意义。但是,添加数组的对象将由数组保留。