Начиная с Objective-C, проблемы утечки памяти - PullRequest
0 голосов
/ 04 июня 2010

Эй, ребята, я начинаю играть с Objective-C и хочу убедиться, что я правильно запоминаю свойства / свойства.

Предположим, следующий код:

@interface Rectangle : NSObject 
{
    Vector2* origin;
    //[...]
}

Rectangle* myRect  = [[Rectangle alloc] init];
myRect.origin.x = 100.0f;
[myRect print];
myRect.origin = [[Vector2 alloc] init]; //hummm.. 2 concerns here.

Концерн 1:

Предположим, происхождение является стандартным (присваиваемым) синтезированным свойством:

Считается ли предыдущий счетчик исходных значений myRect автоматически равным 0 при назначении нового Vector2, и GC позаботится об этом позже? Или я должен явно вызвать release внутри свойства?

Концерн 2:

Предположим, что origin будет свойством 'retain': (Кстати: будет ли этот код генерироваться автоматически при объявлении синтезированного свойства retain, возможно ли это?)

-(void) setOrigin: (Vector2*)newOrigin {
   [newOrigin retain];
   [origin release]
   origin = newOrigin;
}

Тогда при выполнении:

myRect.origin = [[Vector2 alloc] init]

Не приведет ли это к двойному приращению счетчика ссылок, а затем к необходимости повторного вызова release, чтобы избежать утечки? Ребята, вы полагаетесь на хорошо документированный код (чтобы знать, что это свойство сохранения) при использовании библиотек / кода других людей, чтобы избежать таких проблем, или есть более безопасные способы выделения объектов / инициализации объектов?

Спасибо за советы!

1 Ответ

4 голосов
/ 04 июня 2010

Концерн 1:
[...] Считает ли предыдущий исходный счетчик myRect значение 0 автоматически

Нет, свойство assign делает то, что говорит, - assign. Он не сохраняет и не освобождает - в этом случае вы должны обрабатывать это вручную.

Концерн 2:

myRect.origin = [[Vector2 alloc] init]

Не приведет ли это к двойному увеличению счетчика ссылок

Да, поэтому вы должны использовать авто-релиз:

myRect.origin = [[[Vector2 alloc] init] autorelease];

... или отпустите вручную:

Vector2 *v = [[Vector2 alloc] init];
myRect.origin = v;
[v release];

Как решить эти проблемы:

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