“(ClassName *)”的功能是什么

时间:2013-05-22 07:54:44

标签: objective-c class syntax casting

我见过使用'(ClassName *)'引用某些对象的代码语句,例如UITableViewCell *myCell = (UITableViewCell*)[self.view viewWithTag:1];

我不知道这意味着什么或它是如何运作的,我想增加对这个概念的理解。

我还看到在方法声明中也使用相同的代码,并且想要了解它是否使用相同的概念,如果不是,它是如何不同的,例如,

-(IBAction)myAction:(id)sender;

2 个答案:

答案 0 :(得分:9)

这是一个类型转换。它将指针的类型转换为括号内的类型。在这种情况下,它将UIView实例(`viewWithTag:的结果)转换为UITableViewCell的实例。

在ObjC中,对象类型转换的对象不会导致类型转换。也就是说 - 没有创建新实例。此外,在执行动态向下转换时,类型转换对象不执行动态类型检查(与C ++中的dynamic_cast不同,或者在Java中进行类型转换,可能会抛出异常)。

因为-viewWithTag:在OS X上返回UIView(或NSView),所以使用类型转换来告诉编译器“没关系 - 我知道返回的这个类型是{{1实例“。使用类型转换允许您在变量的赋值表达式中从UITableViewCell向下转换为其子类UIView,这允许您将对象用作UITableViewCell,并使编译器与消息匹配或变量与类型。如果没有类型转换,您可以在逻辑上将其用作UITableViewCell(或其中一个超类),如果您尝试使用实例的子类实现的方法,编译器会抱怨。例如 - 如果没有类型转换,类型擦除或编译器警告或错误,您无法成功使用该变量来访问UITableViewCell.accessoryView属性。在这种情况下,类型转换是最不邪恶的。

现在在UIView的情况下,- (IBAction)myAction:(id)sender;是一个无类型的ObjC对象。它有一个特殊的区别,它不需要进行类型转换。例如:

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.

答案 1 :(得分:0)

只是抑制编译器警告所必需的类型转换。 换句话说,它对编译器[self.view viewWithTag:1]的说法是一个UITableViewCell。如果没有这个演员,编译器会抱怨UIView不是UITableViewCell。