iOS - viewDidUnload странный вызов - PullRequest
0 голосов
/ 05 июля 2011

Я читал книгу «Начало разработки iPhone 4», и у них есть одно руководство по использованию контроллеров навигации. В этом уроке мы помещаем контроллер представления (с именем childController) в представление. Но поскольку мы не хотим «выставлять» этот контроллер для других классов, мы не создали для него никаких методов доступа. Так в viewDidUnload авторы написали:

- (void)viewDidUnload {
    [childController release], childController = nil;
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

Я правда не понимаю запятую после релиза? Этот код на самом деле работает для меня. Я не получил никаких ошибок или утечек памяти.

Но, насколько я понимаю, не должно быть так:

- (void)viewDidUnload {
    [childController release]; 
    childController = nil;
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

Ответы [ 2 ]

4 голосов
/ 05 июля 2011

Оператор запятой в C оценивает оба своих операнда (они должны быть выражениями, а не операторами), отбрасывая первый операнд и возвращая значение второго операнда. В вашем примере:

[childController release], childController = nil;

компилятор делает следующее:

  1. Оценить [childController release] (эффективно отправив -release в childController) и отбросить возвращаемое значение (которое, в случае -release, равно void);
  2. Оценить childController = nil. Это выражение присваивания, которое назначает второй операнд (nil) первому операнду childController и возвращает значение левого операнда в присваивании;
  3. Возвращает значение второго операнда (childController, который содержит nil).

Поскольку C позволяет не использовать значение выражения, значение [childController release], childController = nil (то есть nil) отбрасывается.

На практике это эквивалентно выполнению:

[childController release]; 
childController = nil;

но некоторые программисты предпочитают использовать выражение из-за тесной связи между выпуском переменной экземпляра и присвоением ей nil. Это визуально ясно (и легко обнаружить ошибки, например, забыть присваивание nil); сравнить:

[childController release], childController = nil;
[someIvar0       release], someIvar0       = nil;
[someIvar1       release], someIvar1       = nil;
[someIvar2       release], someIvar2       = nil;

с:

[childController release]; 
childController = nil;
[someIvar0       release]; 
someIvar0       = nil;
[someIvar1       release]; 
someIvar1       = nil;
[someIvar2       release]; 
someIvar2       = nil;

Это вопрос стиля.

Редактировать: Eiko упомянула в комментарии, что следующее, которое не использует запятую, является еще одним вариантом:

[childController release]; childController = nil;
[someIvar0       release]; someIvar0       = nil;
[someIvar1       release]; someIvar1       = nil;
[someIvar2       release]; someIvar2       = nil;
3 голосов
/ 05 июля 2011
 [childController release], childController = nil;

это обычный оператор C, запятая , предназначенный для "секвенирования" выражений.на самом деле, в этом случае это полностью эквивалентно:

[childController release];
childController = nil;

единственное, что изменяется, это читаемость (в худшую или лучшую сторону, это зависит ...)

, но в целомОператор секвенирования вычисляет значение последнего оператора (т. е. значения всех операндов отбрасываются, кроме последнего).

int a, b;
int c = (a = 1), (b = 2);

c будет равно 2 после выполнения этого оператора.

РЕДАКТИРОВАТЬ: по ссылке, которую я добавил:

Вряд ли есть причина использовать оператор запятой где-либо, кроме первого и третьего управляющих выражений цикла for, и фактическибольшинство запятых, которые вы видите в программах на C, не являются операторами запятых.В частности, запятые между аргументами в вызове функции не являются операторами запятых;это просто знаки препинания, которые разделяют несколько выражений аргументов.Довольно легко понять, что они не могут быть запятыми, в противном случае при вызове, подобном

edit: лучший пример:

int a = 1;
int b = 2;
b = printf("%d, %d", a,b), a+b;

, сначала будет напечатано:

1, 2

, затем назначьте 3 для b.

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