Objective-C: автоматически выпущенный объект как параметр для метода - PullRequest
0 голосов
/ 22 сентября 2011

может ли следующий код привести к проблемам?

- (void) method1 {
      NSMutableArray *myArray = [[[NSMutableArray alloc] init] autorelease];

      ... fill the array

      [someObject someMethod:myArray]; // someObject does work on that array (without retain!)
}

Иногда возникающее сбой в моем приложении выглядит так, как будто это проблема;но я бы не понял, что ... не должен ли myArray остаться в живых хотя бы до конца метода1?

Большое спасибо за вашу помощь!

Так что мои вопросы помимо этого "могут липроблема "заключается в следующем: - будет ли достаточно удалить авто-релиз и сделать релиз в конце метода?- если нет: я должен сделать сохранение / выпуск в "someMethod"?

РЕДАКТИРОВАТЬ: но это может быть проблемой, я прав?

- (void) method1 {
      NSMutableArray *myArray = [self getArray];

      ... fill the array

      [someObject someMethod:myArray]; // someObject does work on that array (without retain!)
}

- (NSMutableArray) method2 {
      return [[[NSMutableArray alloc] init] autorelease];
}

Ответы [ 4 ]

0 голосов
/ 22 сентября 2011

Ваш код полностью правильный .Не слушайте людей, говорящих вам, чтобы удалить авто-релиз и вручную освободить массив после вызова someMethod:.

. В 99% случаев использование объекта autorelease'd абсолютно нетнегативное влияние на производительность вашего приложения.Единственное, о чем вы хотите беспокоиться - это циклы.

Шаблон [[[Foo alloc] init] autorelease] такой же, как и при использовании встроенного вспомогательного метода, такого как [NSString stringWithFormat:...].Они оба возвращают автоматически выпущенный объект, но вы, вероятно, не беспокоитесь о производительности последнего.Опять же, беспокойтесь только об автоматическом выпуске в больших циклах, или когда Instruments сообщит вам, что у вас есть проблема.

Использование стиля [[[Foo alloc] init] autorelease] также сохраняет все управление памятью в одной строке.Если вы привыкнете печатать [[[, вы не забудете релиз.Если вы копируете и вставляете код или перемещаете код, вы случайно не потеряете соответствующий release, потому что он все в одной строке.

Также проще просмотреть код, который использует [[[Foo alloc] init] autorelease]стиль, потому что вам не нужно искать 1020 * дальше по методу, чтобы убедиться в правильности управления памятью.

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

Ваша проблема с аварийным завершением должна быть вызвана каким-то другим фактором, который не очевиден в опубликованном вами коде.

Я также предлагаю вам прочитать Руководство по программированию управления памятью , если вы этого еще не сделали.По сути, объект autorelease'd гарантированно остается действительным до тех пор, пока не будет освобожден окружающий пул.В вашем случае пул авто-выпусков находится выше в стеке вызовов (возможно, в главном цикле выполнения), поэтому вы можете быть уверены в том, что ваш массив autorelease'd будет оставаться действительным в течение любых ваших вызовов.

Последний пункт.В вашем коде выделения массива также может использоваться вспомогательный конструктор array:

NSMutableArray *myArray = [NSMutableArray array];

Это даже проще, чище и короче, чем ваш оригинал.

0 голосов
/ 22 сентября 2011

Похоже, вам не хватает пары открытых скобок в строке, где вы размещаете свой массив.Должно быть [[[NSMutableArray alloc] init] autorelease];

0 голосов
/ 22 сентября 2011

Лучше всего будет что-то вроде этого:

- (void) method1 {
      NSMutableArray *myArray = [[NSMutableArray alloc] init];

      ... fill the array

      [someObject someMethod:myArray]; // someObject does work on that array (without retain!)
      [myArray release];
}

и лучше всего с двух разных точек зрения. Один из способов, которым вы держите свой массив, пока он вам не понадобится, поэтому он не сотрет память, пока вы так не скажете. Второе - это то же самое предложение, только причина в том, что вы очистите память от ненужных объектов, как только это можно будет сделать.
Последнее может нуждаться в дополнительном объяснении ... Автоматически освобожденные объекты должны быть автоматически освобождены, как только вам это не нужно, но они выпускаются по двум основным правилам: в конце блока (не всегда) или при нагрузке на память после конца блока (да всегда). Другими словами, NSAutoreleasePool не всегда выпускает материал в конце некоторого блока кода, и даже нередко бывает, что он задерживает эти выпуски на более позднюю точку.
В любом случае, вы всегда должны проверять, не слишком ли выпущен ваш объект, поскольку это приведет к падению, когда вы попытаетесь достичь такого объекта в своем коде.

0 голосов
/ 22 сентября 2011

Я собираюсь на мгновение предположить, что вы имели в виду, что это будет NSMutableArray, а не NSArray.Если вы действительно имеете в виду NSArray здесь, то все это невозможно.Вы не можете "заполнить массив" в неизменяемом массиве.

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

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