我创建了一个 NSArray 实例,而它的 class 不是 NSArray 而是 __NSArrayI?
I created an instance of NSArray, whereas whose class is not NSArray but __NSArrayI?
我有以下代码:
id anArray = [NSArray arrayWithObjects:@1, @2, nil];
NSLog(@"anArrayClass - %@", [anArray class]);
NSLog(@"NSArrayClass - %@", [NSArray class]);
我希望两个输出都是 NSArray
,但输出结果是:
2016-08-18 21:08:53.628 TestUse[9279:939745] anArrayClass - __NSArrayI
2016-08-18 21:08:53.629 TestUse[9279:939745] NSArrayClass - NSArray
然后我创建一个名为 CAJTestClass
的测试 class 并创建该 class 的实例:
id testInstance = [CAJTestClass new];
NSLog(@"testInstanceClass - %@", [testInstance class]);
NSLog(@"cajTestClass - %@", [CAJTestClass class]);
这次输出变成:
2016-08-18 21:08:53.629 TestUse[9279:939745] testInstanceClass - CAJTestClass
2016-08-18 21:08:53.629 TestUse[9279:939745] cajTestClass - CAJTestClass
这次的结果是我意料之中的。但是为什么 [anArray class]
会变成 __NSArrayI
?
"Effective Objective-C" 的解释是 NSArray
是 "class cluster" 的一部分(我认为这是一系列具有继承关系的 classes)。但是 CAJTestClass
也是 NSObject
的子 class。我错了吗?
编辑:感谢您的所有回答。但我的问题是,如果它应该有助于 "class cluster"?
的事务,那么为什么在这两种情况下我会得到不同的结果
在您的软件开发中,您唯一担心的 classES 是 NSArray 和 NSMutableArray。在幕后,有许多不同的 classes。例如,空数组的单例 class。 A class 表示具有一个数组元素的数组。所有这些都节省了内存,因为人们使用了大量的琐碎数组。
__NSArrayI 是不可变数组的代码字 - 也就是说,您无法更改的 "regular" NSArray。
__NSArrayM 是可变数组的代码字 - 即 NSMutableArray。在 NSMutableArray 中,您可以添加和删除项目。
__NSArrayI
指的是数组的不可变版本,初始化后不能更改。
__NSArrayI 表示 NSArray 的不可变形式。还有 __NSArrayM,这是可变形式。不可变的意思是你不能改变它,这个数组里面的对象不能改变。对于可变的,您可以更改元素。你也可以看看这个post。我认为这也回答了你的问题。 What is __NSArrayI and __NSArrayM? How to convert to NSArray?
__NSArrayI
是不可变 NSArray
的私有 class。还有 __NSArrayM
,它是可变数组的私有 class。两者都是 NSArray
的子class
+ arrayWithObjects:
returns a __NSArrayI
你无能为力,因为这是私有的 API 你不能用于应用程序商店分发。
如果你想检查你的对象是 NSArray
你可以使用
if ([anArray isKindOfClass:[NSArray class]]){
//blablabla
}
EDIT: Thanks for all your answers. But my question is exactly why I get different result in this two cases if it should contribute to the affairs of "class cluster"?
因为测试代码完全不同。您调用的 NSArray
方法 return 是 NSArray
的子 class,但您调用的 [CAJTestClass new]
是 return 的 CAJTestClass
本身。如果你让它们相同,那么你会得到相同的结果:
@interface CAJTestClass : NSObject
+ (instancetype)testClassWithMagic;
@end
@interface __MagicTestSubclass : CAJTestClass
@end
@implementation CAJTestClass
+ (instancetype)testClassWithMagic {
return [__MagicTestSubclass new];
}
@end
@implementation __MagicTestSubclass
@end
现在使用您的测试代码:
id testInstance = [CAJTestClass testClassWithMagic];
NSLog(@"testInstanceClass - %@", [testInstance class]);
NSLog(@"cajTestClass - %@", [CAJTestClass class]);
2016-08-18 09:57:15.126 test[72004:47882338] testInstanceClass - __MagicTestSubclass
2016-08-18 09:57:15.127 test[72004:47882338] cajTestClass - CAJTestClass
rmaddy 提出了您有不同问题的可能性,他可能是正确的,所以我也会回答那个问题。
[anArray class]
是将-class
消息传递给实例anArray
的结果。实例在收到 -class
消息时通常要做的事情是 return 它被初始化为的特定 class (它的特定子 class )。这不是通用的(KVO classes 有意打破这条规则,甚至可以在运行时更改 classes),但这是常见的方法。这是结构中的 isa
指针,它告诉调度程序要使用哪组方法。所以你得到了实际的实例化 class 对象 (__NSArrayI
).
[NSArray class]
是将+class
消息传递给class对象NSArray
的结果。 class 对象的通常对象是 return self
(我不知道有任何 class 违反该规则;违反该规则可能不合法).所以你得到 class 你将消息传递给 (NSArray
).
我有以下代码:
id anArray = [NSArray arrayWithObjects:@1, @2, nil];
NSLog(@"anArrayClass - %@", [anArray class]);
NSLog(@"NSArrayClass - %@", [NSArray class]);
我希望两个输出都是 NSArray
,但输出结果是:
2016-08-18 21:08:53.628 TestUse[9279:939745] anArrayClass - __NSArrayI
2016-08-18 21:08:53.629 TestUse[9279:939745] NSArrayClass - NSArray
然后我创建一个名为 CAJTestClass
的测试 class 并创建该 class 的实例:
id testInstance = [CAJTestClass new];
NSLog(@"testInstanceClass - %@", [testInstance class]);
NSLog(@"cajTestClass - %@", [CAJTestClass class]);
这次输出变成:
2016-08-18 21:08:53.629 TestUse[9279:939745] testInstanceClass - CAJTestClass
2016-08-18 21:08:53.629 TestUse[9279:939745] cajTestClass - CAJTestClass
这次的结果是我意料之中的。但是为什么 [anArray class]
会变成 __NSArrayI
?
"Effective Objective-C" 的解释是 NSArray
是 "class cluster" 的一部分(我认为这是一系列具有继承关系的 classes)。但是 CAJTestClass
也是 NSObject
的子 class。我错了吗?
编辑:感谢您的所有回答。但我的问题是,如果它应该有助于 "class cluster"?
的事务,那么为什么在这两种情况下我会得到不同的结果在您的软件开发中,您唯一担心的 classES 是 NSArray 和 NSMutableArray。在幕后,有许多不同的 classes。例如,空数组的单例 class。 A class 表示具有一个数组元素的数组。所有这些都节省了内存,因为人们使用了大量的琐碎数组。
__NSArrayI 是不可变数组的代码字 - 也就是说,您无法更改的 "regular" NSArray。
__NSArrayM 是可变数组的代码字 - 即 NSMutableArray。在 NSMutableArray 中,您可以添加和删除项目。
__NSArrayI
指的是数组的不可变版本,初始化后不能更改。
__NSArrayI 表示 NSArray 的不可变形式。还有 __NSArrayM,这是可变形式。不可变的意思是你不能改变它,这个数组里面的对象不能改变。对于可变的,您可以更改元素。你也可以看看这个post。我认为这也回答了你的问题。 What is __NSArrayI and __NSArrayM? How to convert to NSArray?
__NSArrayI
是不可变 NSArray
的私有 class。还有 __NSArrayM
,它是可变数组的私有 class。两者都是 NSArray
+ arrayWithObjects:
returns a __NSArrayI
你无能为力,因为这是私有的 API 你不能用于应用程序商店分发。
如果你想检查你的对象是 NSArray
你可以使用
if ([anArray isKindOfClass:[NSArray class]]){
//blablabla
}
EDIT: Thanks for all your answers. But my question is exactly why I get different result in this two cases if it should contribute to the affairs of "class cluster"?
因为测试代码完全不同。您调用的 NSArray
方法 return 是 NSArray
的子 class,但您调用的 [CAJTestClass new]
是 return 的 CAJTestClass
本身。如果你让它们相同,那么你会得到相同的结果:
@interface CAJTestClass : NSObject
+ (instancetype)testClassWithMagic;
@end
@interface __MagicTestSubclass : CAJTestClass
@end
@implementation CAJTestClass
+ (instancetype)testClassWithMagic {
return [__MagicTestSubclass new];
}
@end
@implementation __MagicTestSubclass
@end
现在使用您的测试代码:
id testInstance = [CAJTestClass testClassWithMagic];
NSLog(@"testInstanceClass - %@", [testInstance class]);
NSLog(@"cajTestClass - %@", [CAJTestClass class]);
2016-08-18 09:57:15.126 test[72004:47882338] testInstanceClass - __MagicTestSubclass
2016-08-18 09:57:15.127 test[72004:47882338] cajTestClass - CAJTestClass
rmaddy 提出了您有不同问题的可能性,他可能是正确的,所以我也会回答那个问题。
[anArray class]
是将-class
消息传递给实例anArray
的结果。实例在收到 -class
消息时通常要做的事情是 return 它被初始化为的特定 class (它的特定子 class )。这不是通用的(KVO classes 有意打破这条规则,甚至可以在运行时更改 classes),但这是常见的方法。这是结构中的 isa
指针,它告诉调度程序要使用哪组方法。所以你得到了实际的实例化 class 对象 (__NSArrayI
).
[NSArray class]
是将+class
消息传递给class对象NSArray
的结果。 class 对象的通常对象是 return self
(我不知道有任何 class 违反该规则;违反该规则可能不合法).所以你得到 class 你将消息传递给 (NSArray
).