2015-08-28 2 views
0

Я импортирую некоторый старый код ObjC, около 2006 года, к последнему Xcode. Это было написано до эпохи ARC, и у меня нет сильной рутины в предыдущей системе. Ищете некоторые советы о том, как их диагностировать.Утечка объектов, и мне нужно исправить это

Вот пример, один из сотен ...

sym = [ globals addObject:[ [ NCObject alloc ] initWithArray:saved dimension:dimension type:type ] ] ; 

Ошибка не специфичны, мне нужен autorelease вокруг всей вещи, или один сразу же после того, как «тип]»?

Я, кажется, помню, что основное правило заключается в том, что если я вижу inti, мне нужно его автообновить. Есть ли другие случаи, о которых мне нужно подумать?

ответ

1
  1. alloc... (любой метод, который начинается с alloc), new, copy..., mutableCopy... дают вам сохранить объекты (благодаря @jlehr для расширения исходного списка).
  2. Коллекции сохраняют объекты, содержащиеся в них (в вашем случае, globals сохраняет что NCObject, что вы создаете.
  3. Вы должны сбалансировать каждый сохранить , что вы пишете с release или autorelease. Если у вас release в объект, вы не можете использовать его больше, потому что если его retainCount достигнет нуля, он будет освобождаться мгновенно. autoreleased объекта будет жить до ближайшей autoreleasepool стока.

В примере, который вы написали, вы должны либо сбалансировать alloc, так что вы должны либо release ваш NCObject после того, как вы добавили его в массив (если вы release это раньше, то, скорее всего, будет deallocated), или autorelease это когда угодно.

Но я бы порекомендовал вам прочитатьApple. Это коротко. И он описывает все правила, которые вам понадобятся.

+2

Вы имеете в виду 'alloc', а не' init' в этом ответе, правильно? – danh

+0

@ danh, да, извините, спасибо :) Я отредактирую это через минуту. Это почти 3 часа ночи здесь. Время, чтобы заснуть, я думаю :) – FreeNickname

+1

Пункт 1 является неполным: кроме того, 'allocWithZone:', 'copy',' copyWithZone: ',' ​​mutableCopy' и 'mutableCopyWithZone:', и вообще любые методы, имена которых начинаются с 'alloc' или' new', все передают право собственности вызывающему. – jlehr

2

Да. Автореферат прав. Атрибут создает объект rc = + 1. Добавление его в массив делает его +2. Autorelease оставят это на +1, где вы хотите. Освобождение массива globals приведет к возврату в 0, что также является желательным поведением.

Для ясности:

sym = [[NCObject alloc] initWithArray:saved dimension:dimension type:type]; 
[globals addObject:sym]; 
[sym autorelease]; 

Обратите внимание, что release так же хорошо в этом случае (немного лучше, потому что он не оставляет работу autorelease бассейн для последующего использования). Если функция не возвращает sym, вы можете ее освободить.

+0

Если вы не собираетесь встраивать выделение и вставку, использование релиза вместо авторекламы должно работать нормально. Вы используете autorelease inline, потому что хотите уменьшить значение keepCount после того, как массив увеличил его. –

+0

:-) просто редактировал это в @DavidZech – danh

+0

Хорошо, один связанный ... в методе '- (id) init' он делает' self = [super init] ', должен ли я автореклассировать себя? Это кажется странным, но оно следует шаблону. –