Hac*_*ker 1 syntax casting class objective-c
我见过使用'(ClassName*)'引用某些对象的代码语句,比如UITableViewCell *myCell = (UITableViewCell*)[self.view viewWithTag:1];.
我不知道这意味着什么或它是如何工作的,我想增加对这个概念的理解.
我也看到同样的代码也用在方法声明中,并想了解它是否使用相同的概念,如果没有,它是如何不同的,例如
-(IBAction)myAction:(id)sender;
这可以作为一个类型.它将指针的类型转换为括号内的类型.在这种情况下,它将UIView实例(结果`viewWithTag:)转换为实例UITableViewCell.
在ObjC中,对象类型转换的对象不会导致类型转换.也就是说 - 没有创建新实例.此外,在执行动态向下转换时,类型转换对象不执行动态类型检查(与dynamic_cast在Java中的C++或类型转换不同,可能会抛出异常).
因为-viewWithTag:返回a UIView(或NSView在OS X上),使用类型转换来告诉编译器"它没关系 - 我知道返回的这个类型是一个UITableViewCell实例".使用类型转换允许您在赋值变量的赋值表达式中向下转换UIView为子类UITableViewCell,这允许您将对象用作UITableViewCell与编码匹配消息或变量的类型.如果没有类型转换,您可以在逻辑上将其用作或将其分配给UIView(或其中一个超类),如果您尝试使用实例的子类实现的方法,编译器会抱怨.例如 - 如果没有类型转换,类型擦除或编译器警告或错误,您无法成功使用该变量来访问UITableViewCell.accessoryView属性.在这种情况下,类型转换是最不邪恶的.
现在的情况是- (IBAction)myAction:(id)sender;,id是一个无类型的ObjC对象.它有一个特殊的区别,它不需要进行类型转换.例如:
- (IBAction)myAction:(id)sender
{
NSString * currentTitle = nil;
currentTitle = sender.currentTitle; // << May be ambiguous to the compiler because `id` is not fully typed
UIButton * button = sender; // << OK assign id to variable of arbitrary ObjC object type
currentTitle = button.currentTitle; // << OK
UIButton * castButton = (UIButton*)sender; // << although unnecessary, some people use this form.
currentTitle = castButton.currentTitle; // << OK
...
NSObject * object = button; // << OK. upcast from button to object. compiler knows it is an NSObject without typecasting.
Run Code Online (Sandbox Code Playgroud)
就个人而言,我只需将其全部包装到参数中 - 只要您知道正在传递的参数的类型,这对于方法声明中的ObjC对象就可以了:
- (IBAction)myAction:(UIButton *)pButton
{
NSString * currentTitle = pButton.currentTitle; // << OK
...
Run Code Online (Sandbox Code Playgroud)