2012-02-14 2 views
2

извините за этот вопрос, но я его обыскал, и я не нашел ответа на этот случай.Как освободить IBOutlet, определенный как свойство?

Я изучаю управление памятью для iOS, и я понял, или я так думаю, жизненный цикл представления. Но теперь у меня вопрос о IBOutlet (tat связан с UIImageView в моем файле xib). У меня есть класс, как это:

@interface MyClass : UIViewController 

@property (nonatomic, retain) IBOutlet UIImageView *myImage; 

Вопрос: как я могу выпустить myImage? Это нормально?

- (void)dealloc { 
    self.myImage = nil; 
    [super dealloc]; 
} 

- (void)viewDidUnload { 
    [super viewDidUnload]; 
    self.myImage = nil; 
} 

Может кто-то объяснить, почему я не могу назвать метод освобождения на MyView (если у вас какой-то Лик это хорошо тоже!)?

Заранее благодарен!

ответ

1

В общем, вы не вызываете release на собственность, вы могли бы назвать его по соответствующему Ивар , Это мой стандартный способ справиться с IBOutlet свойств:

@interface MyClass 

@property (nonatomic, retain) IBOutlet UIImageView *myImageView; 
@property (nonatomic, retain) IBOutlet UILabel *myLabel; 

@end 


@implementation MyClass 

@synthesize myImageView = _myImageView; 
@synthesize myLabel = _myLabel; 


- (void)dealloc { 

    [_myImageView release]; 
    [_myLabel release]; 

    [super dealloc]; 
} 

@end 
+0

Если я пытаюсь использовать ваш код, xCode дает мне ошибку в строке «[_myImageView release]» ... Вот почему я написал вопрос, я не могу понять, почему. –

+0

У вас должен быть включен ARC. –

+0

Это невозможно, я скомпилировал его для iPAD 4.3 (в симуляторе) –

1

То, что вы делаете правильно, и вы обычно shoudnt отбой вызова по свойствам, так как установка на ноль ли это уже, однако, если у вас есть подкладочный Ивар к вашей собственности, вы можете позвонить выпустить на что ...

+0

Спасибо за ответ, можете ли вы дать мне URL-адрес документа, который объясняет это? Потому что это кажется правильным, но я не понимаю, почему :) –

1

За свойством есть свойство и переменная экземпляра. Я думаю, что оба они называются myImage (или вы не будете задавать этот вопрос). Вы можете освободить экземпляр двумя способами: либо релиз, либо ноль ivar, либо просто нуль.

Созданный компилятором сеттер для сохраняемых свойств (например, этот) работает следующим образом: отпустите ссылку на текущий объект (если есть), присвойте новое значение базовому ivar, сохраните его (если не ноль). Поэтому, когда вы назначаете nil свойству, он имеет эффект освобождения текущего значения и замены его на nil.

Чтобы сделать это, используйте

self.myImage = nil; //invoke property setter behind the scenes 

Для освобождения Ивар используйте

[myImage release]; 
myImage = nil; 

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

@synthesize MyImage = _MyImage; 
+0

Проблема в том, что [myImage release] дал мне ошибку, и я не знаю, почему .. –

+0

Возможно, вы слишком много. Скорее всего, ваши точки ивара у объекта зомби - тот, который уже был выпущен в какой-то момент. Прочитайте настройку «NSZombie», включите ее и посмотрите, не так ли. –

+0

Если это ошибка компиляции (в отличие от ошибки во время выполнения) - какой тип 'myImage'? Что такое базовый класс? –

0

Прежде всего: рассмотреть вопрос о переходе на ARC, если вы не поддерживаете IOS версии до 4.0.

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

[myImage release], myImage = nil; 

Наконец, когда СЦЕПЛЕНИЕ вместе де-инициализации методов, как viewDidUnload, всегда вызывать реализацию super «s после того, как вы делаете свою собственную работу.

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

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

+0

Я знаю преимущества с помощью iOS 5, но я должен поддерживать iOS4 .. Проблема в том, что строка [myImage release] дает мне ошибку ... –

+0

Несмотря на то, что ARC был представлен SDK, который сопровождал iOS 5, он обратно совместим с iOS 4, почти прозрачно. Таким образом, вполне возможно, что вы создали проект с включенным ARC. Если вы получаете ошибки компилятора, жалующиеся на вызов 'release', вы практически уверены. – warrenm

+0

НЕТ ждать, ARC не активен (я проверил), и я вызываю метод выпуска сотни раз в моем коде, и он дает мне ошибку только в этом случае. Поэтому я думаю, что это не ошибка, связанная с ARC:) ... –

1

От Apple's documentation:

Унаследованные Шаблоны До АРК, правила для управления Nib объектами являются отличаться от описанных выше. Как управлять объектами зависит от платформы и используемой модели памяти. Какую бы платформу вы не использовали , вы должны определить торговые точки, используя функцию объявленных свойств Objective-C .

Общая форма декларации должна быть:

@property (attributes) IBOutlet UserInterfaceElementClass *anOutlet; 

Поскольку поведение точек зависит от платформы, фактическое объявление отличается:

Для прошивки, вы должны использовать :

@property (nonatomic, retain) IBOutlet UserInterfaceElementClass *anOutlet; 

Для OS X, вы должны использовать:

@property (assign) IBOutlet UserInterfaceElementClass *anOutlet; 

Затем вы должны либо синтезировать соответствующие методы доступа, или осуществить их согласно декларации, и (в прошивке) высвобождает соответствующую переменную в dealloc.

Эта модель также работает, если вы используете современную среду выполнения и синтезировать переменные экземпляра, так что остается неизменным во всех ситуациях.

+0

Это именно то, что я сделал, но xcode дал мне ошибку при вызове [anOutlet release] в моем dealloc ... И я не могу понять, почему. –

+0

Fawk, это действительно странно. У меня много кода работает так. Двойная проверка других возможных проблем. Удачи! –

+0

Не могли бы вы опубликовать ошибку, которую вы получите при реализации этого? –

0

Я не получить то, что вы имеете в виду «почему я не могу вызвать метод освобождения от MyView»

Ваш код кажется правильным для меня, но по соглашению я обычно предпочитаю, чтобы освободить Ивар напрямую для удерживаемого имущества Я обычно синтезируют свою собственность, как это:

@synthesize myImage = _myImage; 

А потом я выпускаю Ивар в методе dealloc

- (void)dealloc { 
    [_myImage release]; 
    [super dealloc]; 
} 

В другом месте в контроллере я просто перехожу на приемник и сеттер (точка-точка)

Ваш видDidUnload верен.

Кстати, если вы используете ARC, просто объявите IBOutlet слабым указателем. Он будет автоматически выпущен в ситуациях с низкой памятью и перезагружен, как только ваше изображение будет загружено обратно.

Надеется, что это поможет;)

+0

Спасибо, но эта строка дает мне ошибку ... [_myImage release]. Я тоже это было правильно, но это кажется ошибкой. Я проверил, и у меня нет ARC (я использую свое приложение на iPad 4.3 в симуляторе) –

+0

Можете ли вы опубликовать сообщение об ошибке? –

3

IBOutlet не имеет никакого отношения иметь дело с управлением памятью.

Но поскольку он сохраняет свойство, вам необходимо его освободить в dealloc.

Так что ваш код верен.

Смежные вопросы