Управление памятью в Objective-C, инициализация нового массива в автоматически выпущенный массив из другой функции - PullRequest
0 голосов
/ 11 октября 2011

Я пытаюсь лучше понять управление памятью. Если у меня есть функция, которая возвращает autorelease NSArray, как это

// DataClass
    - (NSArray *)getData {
       NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease];
       // do some stuff to get data from sqlite
       return array;
    }

затем в другом файле класса, я хочу использовать этот getData. У меня есть собственность

@property (nonatomic, retain) NSArray *myData;

- viewDidLoad {
    NSMutableArray *data = [[NSMutableArray alloc] init];
    data = [DataClass getData];
    self.myData = data;
    [data release];
}

Почему в этом случае возникает ошибка неверного доступа? Я знаю, что это из-за [выпуска данных], но я подумал, что, поскольку метод getData возвращает авто-релиз NSArray, и так как я инициализирую новый NSMutableArray с помощью alloc / init, то мне нужно его освободить? Или происходит то, что происходит, даже если я инициализирую данные с помощью alloc / init, тогда я даже не использую их, потому что с помощью оператора data = [DataClass getData] я указываю на другой NSArray, а затем пытаюсь освободить этот уже автоматически выпущенный NSArray из getData, а затем данные NSMutableArray все еще где-то плавают в памяти? Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 11 октября 2011

Ваше предположение верно. : -)

Прежде всего, как написано, в viewDidLoad вы пропускаете data, который вы выделяете / инициализируете в строке 1, когда назначаете data результат вызова getData в строке 2.

И тогда, вы правы, что data в этот момент указывает на автоматически выпущенный объект. Так что называть release это плохо.

Честно говоря, в вашем методе viewDidLoad вам действительно не нужен вызов getData. Полная и подходящая последовательность для этого вида операции:

NSMutableArray *array = [[NSMutableArray alloc] init];
// here is where you could fill array with your data, or call a method to 
// which you pass array to be filled.
self.data = array;
[array release];

при условии, что свойство данных определено с retain. Используя префикс self., вы получите retain за вас.

Помогает ли это?

0 голосов
/ 11 октября 2011

Есть две возможные проблемы с вашим кодом. Первое наверняка:

 NSMutableArray *data = [[NSMutableArray alloc] init];
 data = [DataClass getData];

Это неправильный шаблон для инициализации объектов. Давайте предположим, что метод класса с именем getData существует и делает то, что вы хотите (что может быть не так, подробнее об этом позже). Первая строка выделяет память для нового массива и возвращает указатель на него. Затем вторая строка немедленно переназначит этот указатель, чтобы он указывал на другой (автоматически освобожденный) массив, пропуская первый массив в процессе.

Во-вторых, ваш метод getData имеет следующую подпись:

- (NSArray *)getData;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...