有没有办法在objective-c中转换对象,就像在VB.NET中转换对象的方式一样?
例如,我正在尝试执行以下操作:
// create the view controller for the selected item FieldEditViewController *myEditController; switch (selectedItemTypeID) { case 3: myEditController = [[SelectionListViewController alloc] init]; myEditController.list = listOfItems; break; case 4: // set myEditController to a diff view controller break; } // load the view [self.navigationController pushViewController:myEditController animated:YES]; [myEditController release];
但是我收到编译器错误,因为'list'属性存在于SelectionListViewController类中,但不存在于FieldEditViewController上,即使SelectionListViewController继承自FieldEditViewController.
这是有道理的,但有没有办法将myEditController转换为SelectionListViewController,以便我可以访问'list'属性?
例如在VB.NET中,我会这样做:
CType(myEditController, SelectionListViewController).list = listOfItems
谢谢您的帮助!
请记住,Objective-C是C的超集,因此类型转换就像在C中一样工作:
myEditController = [[SelectionListViewController alloc] init]; ((SelectionListViewController *)myEditController).list = listOfItems;
((SelectionListViewController *)myEditController).list
更多例子:
int i = (int)19.5f; // (precision is lost) id someObject = [NSMutableArray new]; // you don't need to cast id explicitly
Objective-C中的类型转换很简单:
NSArray *threeViews = @[[UIView new], [UIView new], [UIView new]]; UIView *firstView = (UIView *)threeViews[0];
但是,如果第一个对象不是UIView
并且您尝试使用它会发生什么:
NSArray *threeViews = @[[NSNumber new], [UIView new], [UIView new]]; UIView *firstView = (UIView *)threeViews[0]; CGRect firstViewFrame = firstView.frame; // CRASH!
它会崩溃.并且很容易在这种情况下找到这样的崩溃,但如果这些行在不同的类中并且第三行在100种情况下仅执行一次该怎么办呢.我打赌你的客户会发现这次崩溃,而不是你!一个看似合理的解决方案是提前崩溃,如下所示:
UIView *firstView = (UIView *)threeViews[0]; NSAssert([firstView isKindOfClass:[UIView class]], @"firstView is not UIView");
那些断言看起来不太好,所以我们可以用这个方便的类别来改进它们:
@interface NSObject (TypecastWithAssertion) + (instancetype)typecastWithAssertion:(id)object; @end @implementation NSObject (TypecastWithAssertion) + (instancetype)typecastWithAssertion:(id)object { if (object != nil) NSAssert([object isKindOfClass:[self class]], @"Object %@ is not kind of class %@", object, NSStringFromClass([self class])); return object; } @end
这要好得多:
UIView *firstView = [UIView typecastWithAssertion:[threeViews[0]];
PS对于集合类型安全Xcode 7比类型转换更好 - 泛型