Подтвердить что ты не робот

Вам нужно выпустить IBOulets в dealloc?

Вам нужно выпустить IBOulets в dealloc? Я не уверен в этом, потому что я не выполнял выделение и, как правило, вы только отпустите для того, что вы назвали alloc. Кто-нибудь знает?

4b9b3361

Ответ 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, вам необходимо его освободить.