保留NSArray中的元素

rop*_*ebo 0 cocoa-touch memory-management objective-c ios

我正在以下列方式创建一个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;
}
Run Code Online (Sandbox Code Playgroud)

这是调用方法,它将接收到的数组元素放入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;
    }
Run Code Online (Sandbox Code Playgroud)

这是问题:

没有保留电话

[result addObject:[s retain]];
Run Code Online (Sandbox Code Playgroud)

我无法从我的ViewController访问NSString元素(EXC_BAD_ACCESS)

我正确使用保留在这里吗?

编辑:

 [[result addObject:s] retain];
Run Code Online (Sandbox Code Playgroud)

 [result addObject:[s retain]];
Run Code Online (Sandbox Code Playgroud)

第二行最初是在我的代码中.发布此问题后删除保留并将其重新插入错误的位置.仍然,保留在这里工作,而留下它不.

编辑2:

发现了分析器(CMD + SHIFT + B),发现了几个内存泄漏,删除了它们,EXC_BAD_ACCESS消失了.感谢大家的帮助!

Vik*_*ica 8

[result addObject:s]
Run Code Online (Sandbox Code Playgroud)

没有任何回报,所以没有什么可以保留的.

对象s被数组保留.

NSMutableArray *result = [NSMutableArray arrayWithCapacity:[arr count]];
Run Code Online (Sandbox Code Playgroud)

不会被保留,也不应该保留,因为它是一个本地对象.

您应该熟悉内存规则.命名约定说,名称以"alloc","new","copy"或"mutableCopy"开头的方法必须提供一个retaind对象.所以你的方法似乎没问题,因为它不会从任何一个开始,并返回一个自动释放(=未保留)的对象.这是打电话的责任,保留与否.

另请注意:

return (NSArray*) result;
Run Code Online (Sandbox Code Playgroud)

不要将NSMutableArray转换为NSArray.演员表只告诉编译器它应该期待什么.由于NSMutableArray是一个NSArray,编译器已经知道了.实际上,转换已经由方法签名中的返回定义定义.

编辑
你在方法中做了什么吗?如果不是 - 我不想让你感到苦恼 - 你真的不需要它,就像NSArray *arr = [str componentsSeparatedByString:@" "];你想要的那样.如果你真的想要@" "远离调用者,你应该考虑在类似的东西上使用类别.NSStringcomponentsSeparatedByBlank

它可能看起来像

@interface NSString (Separation)
-(NSArray *)componentsSeparatedByBlank;
@end

@implementation NSString (Separation)
-(NSArray *)componentsSeparatedByBlank
{
    return [self componentsSeparatedByString:@" "];
}
@end
Run Code Online (Sandbox Code Playgroud)

或者使用空格字符集:

-(NSArray *)componentsSeparatedByWhiteSpace
{
    NSArray *array = [self componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceCharacterSet]];
    return [array filteredArrayUsingPredicate: [NSPredicate predicateWithFormat:@"SELF != ''"]];
}
Run Code Online (Sandbox Code Playgroud)