Cómo lanzar un objeto en Objective-C

¿Hay alguna manera de lanzar objetos en Objectic c de forma parecida a cómo se lanzan los objetos en VB.NET?

Por ejemplo, estoy tratando de hacer lo siguiente:

// 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]; 

Sin embargo, estoy obteniendo un error de comstackción ya que la propiedad ‘list’ existe en la clase SelectionListViewController pero no en FieldEditViewController aunque SelectionListViewController hereda de FieldEditViewController.

Esto tiene sentido, pero ¿hay alguna forma de convertir myEditController a SelectionListViewController para que pueda acceder a la propiedad ‘list’?

Por ejemplo, en VB.NET haría:

 CType(myEditController, SelectionListViewController).list = listOfItems 

¡Gracias por la ayuda!

Recuerde, Objective-C es un superconjunto de C, por lo que el encasillado funciona como lo hace en C:

 myEditController = [[SelectionListViewController alloc] init]; ((SelectionListViewController *)myEditController).list = listOfItems; 
 ((SelectionListViewController *)myEditController).list 

Más ejemplos:

 int i = (int)19.5f; // (precision is lost) id someObject = [NSMutableArray new]; // you don't need to cast id explicitly 

Typecasting en Objective-C es fácil como:

 NSArray *threeViews = @[[UIView new], [UIView new], [UIView new]]; UIView *firstView = (UIView *)threeViews[0]; 

Sin embargo, ¿qué pasa si el primer objeto no es UIView e intentas usarlo?

 NSArray *threeViews = @[[NSNumber new], [UIView new], [UIView new]]; UIView *firstView = (UIView *)threeViews[0]; CGRect firstViewFrame = firstView.frame; // CRASH! 

Se bloqueará. Y es fácil encontrar tal locking para este caso, pero ¿qué pasa si esas líneas están en diferentes clases y la tercera línea se ejecuta solo una vez en 100 casos? ¡Apuesto a que tus clientes encuentran este choque, no tú! Una solución plausible es colgarse temprano , así:

 UIView *firstView = (UIView *)threeViews[0]; NSAssert([firstView isKindOfClass:[UIView class]], @"firstView is not UIView"); 

Esas afirmaciones no se ven muy bien, así que podríamos mejorarlas con esta útil categoría:

 @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 

Esto es mucho mejor:

 UIView *firstView = [UIView typecastWithAssertion:[threeViews[0]]; 

PS para colecciones tipo seguridad Xcode 7 tiene mucho mejor que encasillamiento – generics

Claro, la syntax es exactamente la misma que C – NewObj* pNew = (NewObj*)oldObj;

En esta situación, es posible que desee considerar el suministro de esta lista como un parámetro para el constructor, algo así como:

 // SelectionListViewController -(id) initWith:(SomeListClass*)anItemList { self = [super init]; if ( self ) { [self setList: anItemList]; } return self; } 

Entonces úsalo así:

 myEditController = [[SelectionListViewController alloc] initWith: listOfItems]; 

Casting para inclusión es tan importante como el casting para la exclusión de un progtwigdor de C ++. La conversión de tipos no es lo mismo que con RTTI en el sentido de que puedes convertir un objeto en cualquier tipo y el puntero resultante no será nulo.