Вам нужно выпустить IBOulets в dealloc? Я не уверен в этом, потому что я не выполнял выделение и, как правило, вы только отпустите для того, что вы назвали alloc. Кто-нибудь знает?
Вам нужно выпустить IBOulets в dealloc?
Ответ 1
Ваши IBOutlets, вероятно, @properties
. Если они есть, и у вас есть retain
как атрибут, тогда вам нужно освободить в -dealloc
Другими словами:
@interface MyViewController : UIViewController {
IBOutlet UITableView *myTable;
}
@property (nonatomic, retain) IBOutlet UITableView *myTable;
@end
Вам нужно [myTable release];
в вашем dealloc.
Если вы создадите новое приложение на основе навигации в Xcode и посмотрите в appdelegate.h:
@interface Untitled1AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navigationController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@end
и dealloc для appdelegate.m:
- (void)dealloc {
[navigationController release];
[window release];
[super dealloc];
}
Ключевыми моделями здесь являются такие строки, как:
@property (nonatomic, retain) IBOutlet UIWindow *window;
Если есть удержание, это означает, что свойство "принадлежит" вашим кодом, и вы должны его освободить.
Конечно, есть и другие способы, например, не объявлять IBOutlets как свойства или объявлять их как свойства без сохранения. Я нахожу, что в большинстве случаев я предпочитаю, чтобы у них были сохраненные свойства, которые я тогда должен явно освободить. Примером этого является переключение с одного контроллера на другой. Поскольку один диспетчер представлений отклонен, его представления удаляются, и они освобождаются. Любые IBUutlet UILabels в этом представлении будут выпущены, если я их не сохраню. Это означает, что когда я перехожу назад к старому виду, мне нужно пройти через reset мои метки и элементы управления до их последних значений, когда я мог бы сэкономить их, если я просто сохраню IBOutlet.
Ответ 2
Если вы просто используете IBOutlet в своем интерфейсе, вам НЕ нужно их выпускать. Причина в том, что, если вы явно не сохранили их в своем коде, они просто устанавливаются. Они придерживаются, потому что вид есть. Очевидно, что если вы также используете свойства и сохраняете их, вам нужно освободить на dealloc.
Ответ 3
Это не про IBOutlet, это про вашу декларацию. Если вы используете новый мастер проекта в Xcode, вы, вероятно, получите такой код в своем заголовочном файле.
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
Вы можете видеть, что сохранить ключевое слово в файле заголовка. Следуя руководству по управлению памятью, вы ДОЛЖНЫ освободить все, что вы сохраните (вызывая выделение, копирование, сохранение и т.д.). И у вас сохранить в вашем коде, тогда вы должны отпустить его.
Кроме того, мастер уже добавляет вам код выпуска.
- (void)dealloc {
[tabBarController release];
[window release];
[super dealloc];
}
Ответ 4
Как вы сказали, вы должны освободить все, что вы выделили (с помощью alloc
или copy
). Это работает по-другому: вы не должны выпускать любые объекты Cocoa, которые вы не выделяли сами (некоторые функции CoreFoundation распределяются, и вы несете ответственность за их освобождение, но это не так).
Если вы не присвоили свой IBOutlet, вам не нужно его выпускать, если, конечно, по какой-то причине вы его не сохранили.
Ответ 5
Чтобы ответить на вопрос Джо д'Андреи. Вы можете использовать self.label = nil;
. Потому что он вызывает setLabel, который сгенерирован автоматически:
- (void)setLabel:(UILabel *)input
{
[label autorelease];
label = [input retain];
}
Как вы можете видеть, текущий label
будет выпущен, тогда nil
присваивается метке.
Но убедитесь, что вы не пишете его как label = nil
. Это не будет работать.
Потому что вам нужно вызвать метод автоматической генерации меток метки.
Ответ 6
Вот что я делал в отношении объектов IBOutlet
(в сочетании с файлом NIB):
@interface MyViewController : UIViewController {
UILabel *label;
}
@property (nonatomic, retain) IBOutlet UILabel *label;
@end
@implementation MyViewController
@synthesize label;
- (void)setView:(UIView *)aView {
if (!aView) {
// view is being set to nil
// set outlets to nil to get the benefit of the didReceiveMemoryWarning!
self.label = nil;
}
// Invoke super implementation last
[super setView:aView];
}
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.label = nil;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)dealloc {
[label release];
[super dealloc];
}
Боковой вопрос: имеет ли смысл использовать self.label = nil
в dealloc или должен быть явно вызван release
(например, чтобы сохранить статический анализатор счастливым)?
Я предполагаю, что в этот момент мы все равно выходим, поэтому нет необходимости устанавливать наши объекты IBOutlet в nil.
Ответ 7
Если это ваш BlahViewController.h:
// BlahViewController.h
#import <UIKit/UIKit.h>
@interface BlahViewController
{
IBOutlet UINavigationBar *navigationBar;
}
@property (nonatomic, retain) IBOutlet UINavigationBar *navigationBar;
@end
Тогда это будет ваш dealloc
в BlahViewController.m:
- (void)dealloc
{
[navigationBar release];
[super dealloc];
}
Однако, если это ваш BlahViewController.h:
// BlahViewController.h
#import <UIKit/UIKit.h>
@interface BlahViewController
{
IBOutlet UINavigationBar *navigationBar;
}
@end
Тогда это будет ваш dealloc
в BlahViewController.m:
- (void)dealloc
{
[super dealloc];
}
И, наконец, если это ваш BlahViewController.h:
// BlahViewController.h
#import <UIKit/UIKit.h>
@interface BlahViewController
{
IBOutlet UINavigationBar *navigationBar;
IBOutlet MKMapView *map;
}
@property (nonatomic, retain) IBOutlet UINavigationBar *navigationBar;
@end
Тогда это будет ваш dealloc
в BlahViewController.m:
- (void)dealloc
{
[navigationBar release];
[super dealloc];
}
Короче говоря, если вы объявите его как свойство, с retain
, вам необходимо его освободить.