Необходимо ли выпустить IBOulets в dealloc?

Взгляните на это .

Запуск с версии 2.5, ядро Linux представило новый механизм записи системного вызова на процессорах Pentium II +. Из-за проблем производительности о процессорах Pentium IV с существующим методом программного прерывания, альтернативный механизм записи системного вызова был реализован с помощью инструкций SYSENTER/SYSEXIT, доступных на процессорах Pentium II +. Эта статья исследует этот новый механизм. Обсуждение ограничено x86 архитектурой, и все листинги исходного кода основаны на ядре Linux 2.6.15.6.

  1. , Что такое системные вызовы?

    Системные вызовы предоставляют процессам пространства пользователя способ запросить сервисы от ядра. Какие сервисы? Сервисы, которые организованы операционной системой как устройство хранения данных, память, сеть, управление процессами и т.д., Например, если пользовательский процесс хочет считать файл, он должен будет сделать 'открытым' и системные вызовы 'чтения'. Обычно системные вызовы не называют процессы непосредственно. Библиотека C предоставляет интерфейс всем системным вызовам.

  2. , Что происходит в системном вызове?

    фрагмент кода ядра А выполняется по запросу пользовательского процесса. Этот код работает в кольце 0 (с текущим уровнем полномочий - CPL 0), который является высшим уровнем полномочия в x86 архитектуре. Все пользовательские процессы выполняются в кольце 3 (CPL 3).

    Так, для реализации механизма системного вызова, в чем мы нуждаемся,

    1) способ назвать кольцо 0 кодами от кольца 3.

    2) некоторый код ядра для обслуживания запроса.

  3. Старый добрый способ сделать его

    До некоторого времени назад, Linux раньше реализовывал системные вызовы на всех x86 платформах с помощью программных прерываний. Для выполнения системного вызова пользовательский процесс скопирует желаемое число системного вызова в %eax и выполнит 'интервал 0x80'. Это генерирует прерывание 0x80, и процедуру обработки прерывания назовут. Для прерывания 0x80 эта стандартная программа - "весь системные вызовы, обрабатывающие" стандартную программу. Эта стандартная программа выполнится в кольце 0. Эта стандартная программа, как определено в файле/usr/src/linux/arch/i386/kernel/entry. S, сохранит текущее состояние и назовет соответствующий обработчик системных вызовов на основе значения в %eax.

  4. Новый солнечный способ сделать его

    было узнано, что этот метод программного прерывания был намного медленнее на процессорах Pentium IV. Для решения этой проблемы Linus реализовал альтернативный механизм системного вызова для использования в своих интересах инструкций SYSENTER/SYSEXIT, предоставленных всеми процессорами Pentium II +. Прежде, чем идти далее с этим новым способом сделать его, давайте сделаем нас более знакомыми с этими инструкциями.

26
задан erotsppa 7 October 2009 в 03:37
поделиться

5 ответов

Вероятно, ваши IBOutlets - это @properties . Если это так, и у вас есть сохранить в качестве атрибута, то вам нужно освободить в -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 как свойства или объявлять их как свойства без сохранения. Я считаю, что в большинстве случаев я предпочитаю, чтобы они сохраняли свойства, который я затем должен явно выпустить. Примером этого является переключение с одного контроллера представления на другой. Когда один контроллер представления закрывается, его представления удаляются и освобождаются. Любые UILabels IBOutlet в этом представлении также будут выпущены, если я их не сохраню. Это означает, что когда я возвращаюсь к старому представлению, мне нужно пройти и сбросить свои метки и элементы управления до их последних значений, хотя я мог бы легко сохранить их, если бы просто сохранил IBOutlet.

35
ответ дан 28 November 2019 в 06:48
поделиться

Дело не в IBOutlet, а в вашем объявлении. Если вы используете мастер нового проекта в Xcode, вы, вероятно, получите такой код в своем файле заголовка.

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;

Как видите, в файле заголовка есть ключевое слово сохранить . Следуя руководству по управлению памятью, вы ДОЛЖНЫ освободить все, что вы сохраняете (путем вызова alloc, copy, keep и т. Д.). И у вас есть сохранить в коде, тогда вы должны выпустить его.

Кроме того, мастер уже добавил для вас код выпуска.

- (void)dealloc {
    [tabBarController release];
    [window release];
    [super dealloc];
}
8
ответ дан 28 November 2019 в 06:48
поделиться

Если вы просто используете IBOutlet в своем интерфейсе, вам НЕ нужно их выпускать. Причина в том, что, если вы явно не сохраните их в своем коде, они просто устанавливаются. Они остаются, потому что есть вид. Очевидно,

9
ответ дан 28 November 2019 в 06:48
поделиться

Как вы сказал, вы должны освободить все, что вы выделили себе (с помощью alloc или copy ). Это работает по-другому: вы не должны освобождать какие-либо объекты Cocoa, которые вы не выделяли сами (выделяются некоторые функции CoreFoundation, а вы '

2
ответ дан 28 November 2019 в 06:48
поделиться

Вот что я делал в отношении объектов 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's 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.

1
ответ дан 28 November 2019 в 06:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: