Это связано с старшинства операций собственности.
Если вы посмотрите here, вы можете видеть, что точечная нотация имеет более высокий приоритет, чем кастинг.
Так этот код:
(TypeSelectionViewController *)nextViewController.recipe
будет преобразован компилятором на следующее (с точечной нотации просто синтаксический сахар для компилятора.):
(TypeSelectionViewController *)[nextViewController recipe]
Однако мы хотели лить деталь nextViewController
на тип TypeSelectionViewController *
, а не [nextViewController recipe]
часть. Так что это неверно.
Так вместо того, чтобы записать это:
((TypeSelectionViewController *)nextViewController).recipe
, который компилятор преобразует это:
[(TypeSelectionViewController *)nextViewController recipe]
который, что мы хотим.
Обратите внимание на компилятор в сравнении с поведением во время выполнения
Если вы скомпилировать этот пример некорректного литья:
UILabel *label = [[UILabel alloc] init];
NSString *result = (UILabel *)label.text;
Вы получите сообщение, как это от компилятора:
Warning: incompatible pointer types initializing 'NSString *' with an
expression of type 'UILabel *'
Однако код будет работать нормально во время выполнения из-за слабого набора текста Objective C. Вы можете прочитать об этом в LLVM docs, например .:
Действительность преобразования между типами указателей объект не проверяется во время выполнения.
Приоритет оператора. Вы хотите посмотреть '.recipe'' nextViewController' как '(TypeSelectionViewController *)'. Вы не хотите использовать 'nextViewController.recipe' как' (TypeSelectionViewController *) '. – nhgrif