铸造到id的差异比实际类型,目标C

Vjy*_*Vjy 4 objective-c

以下两个陈述之间可能有什么区别?

UILabel *mainLabel = (id) [cell viewWithTag:10];
Run Code Online (Sandbox Code Playgroud)

UILabel *mainLabel = (UILabel*) [cell viewWithTag:10];
Run Code Online (Sandbox Code Playgroud)

Gab*_*lla 7

简答:没有.

两个强制类型转换都会阻止编译器警告指针类型不兼容.

无论如何,因为在运行时没有检查Objective-C中的类型,所以当你运行它时它不会有什么不同.

事实上

UILabel *mainLabel = (id) [cell viewWithTag:10];
UILabel *mainLabel = (UILabel*) [cell viewWithTag:10];
UILabel *mainLabel = [cell viewWithTag:10];
Run Code Online (Sandbox Code Playgroud)

完全在运行时等价的.

唯一明显的区别是编译器会在第三种情况下警告您,因为类型似乎不兼容.由于Liskov替换原则,实际上,您不能将通用分配UIView给a UILabel.通过投射它你告诉编译器:"相信我,我知道这将是好的".

然而,从这个角度来看,将它转换为id真正没有意义:你使类型更通用,而你应该将它缩小到适当的子类.

为了将其包装起来,作为一种好的做法,建议您将返回类型转换为您期望的确切类.它会更有意义,而且代码可读性也会更好.

  • 如果不清楚,编译器在将"id"分配给其他东西时从不警告你,即使`id`更通用 (3认同)
  • 正确.通常,"id"的语义类似于:"*编译器,保持不受限制,这将很好地工作*" (2认同)
  • 点符号是一个例外; 在没有编译器抱怨的情况下,你不能将它与`id`一起使用. (2认同)