2013-09-03 2 views
2

У меня возникла странная проблема, которая очень распространена и может плавать на многих сайтах, но это немного странно. Я выделяю объект использования объекта изменяемого массива, а затем освобождаюсь, как я делал, и каждый раз выделяю и отпускаю объект. Он отлично работает, когда я комментирую строку выпуска и просто использую nil. Ниже мой код, пожалуйста, посмотрите и предложите мне лучший способ.Приложение получает сбой при выпуске объекта массива в xcode

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 
{ 
    NSMutableArray * array = [[NSMutableArray alloc] init]; 
    array= [[dbSingleton sharedInstance] getAll_Players]; 
    NSMutableDictionary * dict = [array objectAtIndex:row]; 
    NSString * autoID = [dict objectForKey:@"autoId"]; 
    NSLog(@"%@",[NSString stringWithFormat:@"%@ %@",[dict valueForKey:@"fName"],[dict valueForKey:@"lName"]]); 
    [array release]; 
} 

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

+5

Нет необходимости выделять-init и выделять здесь массив, поскольку вам требуется только ссылка на ваш массив sharedInstance. Удалите эти строки и разделите только свой массив: NSMutableArray * array = [[dbSingleton sharedInstance] getAll_Players]; – Mrunal

+0

, что может быть из-за проекта ARC, поэтому вам не нужно выпускать массив, он будет автоматически выпущен –

+0

@Mrunal Вот и ответ прямо там. Должен быть ответ, а не комментарий. –

ответ

2

Сначала вы инициализировать массив переменной

NSMutableArray * array = [[NSMutableArray alloc] init]; 

И правильно в этой точке, вы должны освободить эту переменную в какой-то момент. Но, когда вы пишете

array= [[dbSingleton sharedInstance] getAll_Players]; 

Вы перезаписать переменную массива вы только выделенные, и массив теперь не то, что вы должны выпустить здесь, если вы не вызовете сохранить в массиве вы получите от getAll_Players.

Чтобы устранить эту проблему, вы должны сделать это следующим образом:

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{ 
NSMutableArray * array = [[dbSingleton sharedInstance] getAll_Players]; 
NSMutableDictionary * dict = [array objectAtIndex:row]; 
NSString * autoID = [dict objectForKey:@"autoId"]; 
NSLog(@"%@",[NSString stringWithFormat:@"%@ %@",[dict valueForKey:@"fName"],[dict valueForKey:@"lName"]]); 
} 

EDIT: (В ответ на вопрос в комментарии)

NSMutableArray * array = [[dbSingleton sharedInstance] getAll_Players]; 

выше строка просто устанавливает «массив переменной 'как указатель на что угодно' [[dbSingleton sharedInstance] getAll_Players] 'возвращается. Счетчик ссылок не увеличивается и не уменьшается в этой строке, и поэтому вы не должны его уменьшать. (И НИКОГДА не доверяйте значению отсчета сохранения для любого объекта, поскольку объекты не всегда выпускаются, когда вы их ожидаете).

Счетчик ссылок увеличивается только при вызове Alloc, новый, скопировать и mutableCopy при создании объекта и вызова сохранить, и объект, и только тогда, когда вы сами использовали эти ключевые слова, если вы когда-либо выпускаете или автоматически проверяете объект. Обратите внимание, что эти ключевые слова увеличивают счетчик RF. Где выпуск и автореферат Уменьшение количества RF.

Ожидается, что объективная практика должна гарантировать, что любая функция, возвращающая объект, возвращает объект с сохраненным числом 0, если только имя функции не имеет одного из указанных выше ключевых слов в его имени. (и вы должны, конечно, называть «autorelease», а не «освобождать» на объекте, прежде чем возвращать его).

При использовании одного из этих ключевых слов приемник должен ожидать, что счетчик RF равен 1, и что приемник будет обязательно освободите объект, когда он или она с ним закончится.

Это то, что вы можете ожидать от любых встроенных функций. Вот почему вы не должны выпускать «массив» объекта из приведенной выше строки.

+0

Нет смысла использовать объект Mutable, так как он делает изменения nog. – rckoenes

+0

Спасибо за ваш ответ Арни, что это за строка "array = [[dbSingleton sharedInstance] getAll_Players];" уменьшает счетчик ссылок или повторно инициализирует объект? потому что, согласно моему пониманию, когда я выпускаю объект массива, он имеет RF = 1 вместо RF = 0, поэтому [release массива] уменьшает RF = 0, поэтому я думаю, что он должен работать нормально. не так ли? – Aleem

+0

Я отредактировал свой ответ в ответ. – ArniDat

3

Не нужно выделять-init и освобождать массив.

Я думаю, вам не нужен новый массив с тем же контентом, тогда как требуется только ссылка вашего массива sharedInstance.

Для этого, удалите эти строки и только decalre ваш массив:

NSMutableArray *array = [[dbSingleton sharedInstance] getAll_Players]; 

Как вы не Alloc-инициализировать любой массив здесь, нет необходимости выпускать то же самое. Следовательно, никаких проблем с памятью не требуется.

Для макс, чтобы уменьшить счетчик ссылок на то, что вы можете сделать это, сразу же, когда его сделали со ссылкой, свести на нет, что один:

NSMutableArray * array= [[dbSingleton sharedInstance] getAll_Players]; 
    NSMutableDictionary * dict = [array objectAtIndex:row]; 
    NSString * autoID = [dict objectForKey:@"autoId"]; 
    NSLog(@"%@",[NSString stringWithFormat:@"%@ %@",[dict valueForKey:@"fName"],[dict valueForKey:@"lName"]]); 
    array = nil; // not mandatory, it will work without this line as well 

Эта методика будет работать для обоих, ARC или Non -ARC.

Надеюсь, что это поможет.

+0

Я уже проголосовал, но мне также нравится ArniDat Ответ, я комментирую его ответ, любезно отвечаю на этот комментарий, тогда я приму вам ответ. :) – Aleem

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