Управление памятью iPhone - PullRequest
3 голосов
/ 16 января 2010

Я работаю над приложением, и я хотел бы убедиться, что я правильно управляю памятью и высвобождаю все, что должен. В моем методе viewDidLoad я выделяю некоторые переменные, определяя, какой фон применить к представлению (для интернационализации), и приложение работает нормально, если я их не освобождаю.

Проблема в том, что если я отпущу переменные, приложение вылетит. Код от viewDidLoad ниже:

// Set the background image based on the phone's preferred language
NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString *backgroundImageName = [[NSString alloc] init];
backgroundImageName = [NSString stringWithFormat:@"background-%@.png",language];
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:backgroundImageName]];

... do some more initialization stuff ...

// IF THE FOLLOWING ARE RELEASED THE APP WILL CRASH!!!
//[backgroundImageName release];
//[language release];

Почему освобождение переменных backgroundImageName и language приводит к сбою приложения?

Ответы [ 3 ]

6 голосов
/ 16 января 2010
NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];

Здесь language не нужно выпускать, потому что objectAtIndex: автоматически выпускает его для вас.По соглашению, у вас есть объект, если вы alloc ed, new ed или copy ed его, в противном случае вы этого не сделаете.

self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:backgroundImageName]];

Здесь объект UIColorнужно освободить (потому что вы alloc редактировали его).

NSString *backgroundImageName = [[NSString alloc] init];
backgroundImageName = [NSString stringWithFormat:@"background-%@.png",language];

Здесь строка, возвращаемая [[NSString alloc] init], должна быть освобождена (потому что вы alloc редактировали ее).Однако следующая строка изменяет backgroundImageName, указывая на новую автоматически освобожденную строку, теряя последнюю ссылку на исходную строку без ее освобождения (утечка памяти).backgroundImageName не следует выпускать, поскольку он уже выпущен автоматически.

Вы можете избежать утечек, выпустив UIColor и удалив неиспользованную строку.Например:

NSString *backgroundImageName = [NSString stringWithFormat:@"background-%@.png",language];

... и ...

UIColor* backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:backgroundImageName]];
self.view.backgroundColor = backgroundColor;
[backgroundColor release];
0 голосов
/ 16 января 2010

Вы не создаете строку языка; ты просто получаешь обратную ссылку. Только методы, в которых есть «new», «copy» или «alloc» (по соглашению), возвращают неавторизованные объекты. Для всех других методов предполагается, что вы отбросите переменную, поэтому, если вы хотите сохранить ее, вы ДОЛЖНЫ сохранить ее. Обратная сторона этого: вы не должны выпускать эти возвращенные объекты, если ВЫ не сохранили их.

Другая проблема в этом коде заключается в том, что backgroundImageName назначается дважды. Первая инициализация теряется. Избавьтесь от этого, просто оставьте второй и избавьтесь от обоих звонков - они не нужны.

0 голосов
/ 16 января 2010

краткий ответ: когда вы создаете объект, используя конструкторы, у которых нет слова init, вы не несете ответственности за его освобождение

см. это для более подробного объяснения

также память руководство по управлению - отличный ресурс, чтобы узнать больше об управлении памятью в цели c

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