NSArray对象和Casting

我有一个带有属性NSString *name A类。 如果有一个NSArray并在这个数组中添加了许多A对象,那么每次检索对象时都需要进行强制转换吗? 即

 NSString* n = (NSString*)[arr objectAtIndex:1]; 

或者是否有另一种方法可以在java中使用ArrayList arr

NSArray不存储有关其中包含的对象类型的信息。 如果您确定数组中的对象类型,则可以隐式或显式执行强制转换:

 NSString *n = [arr objectAtIndex:1]; // implicit type conversion (coercion) from id to NSString* NSString *n = (NSString *)[arr objectAtIndex:1]; // explicit cast 

隐式和显式转换之间的运行时成本没有区别,这只是风格问题。 如果你输入的类型不对,那么很可能会发生的事情是你会将可怕的unrecognized selector sent to instance 0x12345678exception。

如果您有不同类型对象的异构数组,则需要使用isKindOfClass:方法来测试对象的类:

 id obj = [arr objectAtIndex:1]; if ([obj isKindOfClass:[NSString class] ]) { // It's an NSString, do something with it... NSString *str = obj; ... } 

NSArrayobjectAtIndex:返回id类型的变量。 这大致相当于在Java中返回一个Object-“我们无法保证这个变量的类型。” 但是,在Objective-C中,您可以在没有编译器抱怨的情况下向id变量发送消息。 因此,因为知道该数组只包含A实例,所以您最好向其发送name消息。 例如,以下内容将在没有警告的情况下编译:

 NSString *name = [[array objectAtIndex:0] name]; 

但是,如果要使用点表示法(例如[array objectAtIndex:0].name ),则需要将id转换为A * ,如下所示:

 NSString *name = ((A *)[array objectAtIndex:0]).name; 

这是做到这一点的方法。 实际上,您可以在不转换返回的情况下执行上述操作,因为无论如何您都要将其读入NSString。

这是方式:

 NSMutableArray *objectsArray = [[NSMutableArray alloc] init]; A *a= [[A alloc] init]; [objectsArray addObject:a]; [a release]; 

您不必担心属性类型