2012-06-14 6 views
0

Я создаю массив NSMutable следующим образом:Стопорные элементы в NSArray

-(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; 
} 

Вот вызывающий метод, который помещает полученные элементы массива в собственность 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]]; 

Я не могу получить доступ к элементам NSString из моего ViewController (EXC_BAD_ACCESS)

Правильно ли я с помощью сохранить здесь?

EDIT:

Изменено

[[result addObject:s] retain]; 

в

[result addObject:[s retain]]; 

2-я линия была первоначально в моем коде. Убрано сохранить и вставить его обратно в неправильное место при публикации этого вопроса. По-прежнему, сохраняя здесь работу, оставляя ее, нет.

EDIT 2:

Обнаруженный анализатор (CMD + SHIFT + B), нашел несколько утечек памяти, удалил их и EXC_BAD_ACCESS ушел. Спасибо вам всем за помощь!

ответ

8
[result addObject:s] 

ничего не возвращает, поэтому сохранить нечего.

объект s сохраняется в массиве.

NSMutableArray *result = [NSMutableArray arrayWithCapacity:[arr count]]; 

не будет сохранен и не должен, так как это локальный объект.

Вам необходимо ознакомиться с помощью memory rules. в соглашениях об именах говорят, что метод, имя которого начинается с «alloc», «new», «copy» или «mutableCopy», должно доставить объект keepd. Таким образом, ваш метод просто кажется прекрасным, поскольку он не начинается с любого из них и возвращает объект с автореализацией (= unretained). Это обязанность звонящих, чтобы сохранить или нет.

Также примечание стороны:

return (NSArray*) result; 

обыкновение превратить ваш NSMutableArray в NSArray. Листинг сообщает компилятору, что он должен ожидать. как NSMutableArray является NSArray, компилятор уже знает это. И фактически приведение уже определено определением возврата в сигнатуре метода.


Вы делаете что-то еще в методе?если нет - я не хочу вас огорчать - вам это действительно не нужно, так как NSArray *arr = [str componentsSeparatedByString:@" "]; просто делает то, что вы хотите. Если вы действительно хотите отмерить @" " от вызывающего абонента, вам следует использовать category на NSString, который называется что-то вроде componentsSeparatedByBlank.

это может выглядеть

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

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

или с белым набором пространства символов:

-(NSArray *)componentsSeparatedByWhiteSpace 
{ 
    NSArray *array = [self componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceCharacterSet]]; 
    return [array filteredArrayUsingPredicate: [NSPredicate predicateWithFormat:@"SELF != ''"]]; 
} 
+0

100% согласен, управление памятью обрабатывается MutableArray, это не ваша проблема! – AsTeR

+0

Спасибо за намек на то, что вам не нужно бросать NSMutableArray. Я не знал об этом. Я уже прочитал Политику управления памятью, но пока документ достаточно информативен, он все еще оставляет некоторые вопросительные знаки в моей голове :) – roplacebo

+0

см. Мое редактирование для некоторых дополнительных предложений для вашего кода. – vikingosegundo

2
[[result addObject:s] retain]; 

является метод недействительным. Это означает, что оно не возвращает никакого значения, например:

будет. Вы сохраняете пустоту, которая ничего не сохраняет, потому что пустота ничего не значит. Однако объект, который вы добавляете в массив, сохраняется массивом.

3

Я правильно использую удержание здесь?

№ NSMutableArray сохраняет объекты, которые вы добавляете к нему. Затем он отпускает их, когда вы вызываете remove или когда массив отключен. Вам не нужно называть удержание здесь. Однако это не из-за того, что вы столкнулись с EXC_BAD_ACCESS

Как сказал vikingosegundo, addObject ничего не возвращает, поэтому вызов сохранения на нем дает вам EXC_BAD_ACCESS.

Правильный синтаксис для того, что вы пытаетесь сделать, это (Примечание: нет необходимости делать это, как описано выше)

[result addObject:[s retain]]; // BAD 

Итак, в заключение, просто

[result addObject:s]; // GOOD - s is retained by result 

EDIT * Переписанные плакаты исходный код ...

-(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]; 

Пожалуйста, почитайте на управление памятью и соглашение об именовании, сэкономит вам много времени в будущем.

+0

Спасибо! Тем не менее, строка 1 работает, а строка 2 - нет. Вероятно, две ошибки, которые отменяют друг друга? – roplacebo

+0

Просто посмотрел на ваш код ... вы собирались получить там дубликатов, добавив из массива в тот же массив. Просмотрите следующий код и сравните его с вашим. Я считаю, что это то, что вы хотите сделать (отредактировал мой оригинальный ответ *) –

Смежные вопросы