我有一个类A
与财产NSString *name
。如果有一个NSArray
并将许多A
对象添加到此数组中,每次检索对象时都需要进行强制转换?即NSArray的对象和铸造
NSString* n = (NSString*)[arr objectAtIndex:1];
还是有另一种方式来做到这一点有点像在Java中,你必须ArrayList<A> arr
?
我有一个类A
与财产NSString *name
。如果有一个NSArray
并将许多A
对象添加到此数组中,每次检索对象时都需要进行强制转换?即NSArray的对象和铸造
NSString* n = (NSString*)[arr objectAtIndex:1];
还是有另一种方式来做到这一点有点像在Java中,你必须ArrayList<A> 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 0x12345678
异常。
如果您有不同类型的对象的异构阵列,您需要使用isKindOfClass:
方法来测试对象的类:
id obj = [arr objectAtIndex:1];
if ([obj isKindOfClass:[NSString class] ])
{
// It's an NSString, do something with it...
NSString *str = obj;
...
}
这是做到这一点的方法。无论如何,你可以实际执行上述操作,而无需强制返回,因为你正在将它读入NSString。
这是这样的:
NSMutableArray *objectsArray = [[NSMutableArray alloc] init];
A *a= [[A alloc] init];
[objectsArray addObject:a];
[a release];
您不必担心proprety型
NSArray
的objectAtIndex:
返回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;
perfect ..只是我正在寻找的信息 – Tim
值得注意的是,在运行时无法区分NSStrings和NSMutableStrings,它们都对'isKindOfClass:[NSMutableString class]'回答YES。 – Chuck
@Chuck:我不知道。怎么来的? –
@Chuck:我注意到NSString也向'[myNSString respondsToSelector:@“appendFormat:];'ISTM返回YES,可变和不可变字符串都是由__NSCFString实现的,并且有一些内部标志,告诉它它是否可变或不可变。如果你调用'[myNSString appendFormat:@“world”];'你得到一个异常,但不是一个表明它不响应选择器的异常。显然'appendFormat:'检查不可变标志,如果它被设置,引发一个异常,可变和不可变的字符串实际上是同一个类,'__NSCFString'。 –