查看 Apple iPhoneCoreDataRecipes
的示例代码,我对下面的代码片段有一个问题,来自RecipeDetailViewController.m
:
case TYPE_SECTION:
nextViewController = [[TypeSelectionViewController alloc]
initWithStyle:UITableViewStyleGrouped];
((TypeSelectionViewController *)nextViewController).recipe = recipe;
break;
在第((TypeSelectionViewController *)nextViewController).recipe = recipe
行中,我理解内括号是将视图控制器类型化为TypeSelectionViewController
,但是外括号有什么作用呢?
这与操作的优先级有关。
如果你看这里,你可以看到点符号比强制转换具有更高的优先级。
所以这段代码:
(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文档中阅读有关此内容的更多信息,例如:
对象指针类型之间的转换的有效性不是 在运行时检查。
这是一个强制转换,据说要考虑 nextViewController 是 TypeSelectionViewController 的一个实例,所以你可以使用它的属性配方