Управление памятью iPhone - PullRequest
       2

Управление памятью iPhone

0 голосов
/ 21 октября 2010

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

Как насчет этой ситуации, просто нужно знать, правильно ли я кодировал. Я все еще новичок в разработке для iPhone.

У меня есть класс CustomerRepository, у него есть метод

- (MSMutableArray *) GetAllCustomers() {

  MSMutableArray *customers = [[MSMutableArray alloc] init];

  Customer *cust1 = [[Customer alloc] init];
  cust1.name = @"John";

  Customer *cust2 = [[Customer alloc] init];
  cust2.name = @"Tony";

  [customers addOjbect:cust1];
  [customers addOjbect:cust2];

  [cust1 release];
  [cust2 release];

  return customers;

}

Тогда у меня есть UIViewController

- (void) LoadCustomers() {

      CustomerRepository *repo = [[CustomerRepository alloc] init];

      MSMutableArray *customers = [repo GetAllCustomers];          

      // Iterate through all customers and do something

      [repo release];

} 

Так что в этом случае MSMutableArray никогда не будет выпущен? Где должен быть релиз?

Ответы [ 4 ]

6 голосов
/ 21 октября 2010

Если вы выделите объект в функции, которую вам нужно вернуть из функции, вы не сможете освободить его внутри функции.Правильный способ сделать это - автоматически освободить объект.

MSMutableArray *customers = [[MSMutableArray alloc] init];

// ..... do work

return [customers autorelease];

Этот подход используется конструкторами connivence, такими как

[NSString stringWithString:@"test"];

Этот метод вернет вам автоматически освобожденную строку, чтобы вам не нужно было ее освобождать.

И если вы этого не сделаете, вам следует назвать свою функцию соответствующим образом, чтобы вызывающая сторона знала, что она владеет возвращаемым объектом и, следовательно, должна быть освобождена.Это соглашения, а не правило, налагаемое компилятором или средой выполнения, но соблюдение соглашения чрезвычайно важно, особенно когда в проекте участвует несколько человек.

2 голосов
/ 21 октября 2010

Всякий раз, когда вы создаете и возвращаете объект из метода или функции, этот объект должен иметь значение autorelease d.Исключения составляют случаи, когда метод начинается с Create или New (или, очевидно, Alloc), или когда объект кэшируется в методе.

Другие ответы, предлагающие выпустить его в LoadCustomers неверны, поскольку GetAllCustomers не подразумевает передачу права собственности, как CreateCustomersArray или NewCustomersArray.Однако вы не можете освободить объект в GetAllCustomers, потому что тогда объект будет освобожден до его возвращения.Решение autorelease.

0 голосов
/ 21 октября 2010

он должен быть освобожден в вашем контроллере представления, LoadCustomers(), так как вы выделяете его в вызываемом методе, он все еще принадлежит ВАМ.

0 голосов
/ 21 октября 2010

Массив клиентов должен быть освобожден после того, как вы закончите его итерацию. Вы делегировали создание массива вашему объекту репо, но ваш метод LoadCustomers владеет массивом.

Другой подход заключается в том, чтобы ваша CustomerRepository выставила свойство allCustomers. Вы можете лениво инициализировать массив в своем геттере, а затем освободить массив после освобождения CustomerRepository. Это сохранит ваши вызовы для выделения и освобождения в одном и том же объекте.

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