本来写个小demo测试一个小问题,后来越想越纠结,就查了些资料,在此做个总结吧,主要关于数组和类簇的。balabala...
NSArray *array1 = [NSArray arrayWithObjects:@"11",@"12",@"13", nil];
NSArray *array2 = [NSArray arrayWithObjects:@"21",@"22",@"23", nil];
NSArray *array3 = [NSArray arrayWithObjects:@"31",@"32", nil];
UILabel*label1 = [[UILabel alloc]init];
NSMutableArray *array0 = [[NSMutableArray alloc]initWithObjects:array1,array2,array3,label1, nil];
NSMutableArray *test1 = [[array0 objectAtIndex:2] mutableCopy];
[test1 addObject:@"33"];
id test2 = [array0 lastObject];
//test1是NSMutableArray的一个私有子类的对象。
if ([test1 isMemberOfClass:[NSMutableArray class]]) {
NSLog(@" NSMutableArray");//不会打印
}
if ([test1 isKindOfClass:[NSMutableArray class]]) {
NSLog(@" NSMutableArray");//会打印
}
if ([test2 isMemberOfClass:[UILabel class]]) {
NSLog(@"UILabel");//会打印
}
1. 不可变数组转化成可变数组有2种方法:[NSMutableArray arrayWithArray:array1]或者[array1 mutableCopy],但不能强制转换(NSMutableArray *)array1。
2. 数组的元素是id类型,说明可以存放任意类型。当你把一个UILabel对象存入数组后,这个数组中的这个元素就是具体的UILabel类型了,而不再是范范的id类型。
3. isMemberOfClass:(当前类)、isKindOfClass:(当前类及其子类),用于类簇时要小心!~
官方说法点击打开链接:
Be careful when using this method on objects represented by a class cluster. Because of the nature of class clusters, the object you get back may not always be the type you expected. If you call a method that returns a class cluster, the exact type returned by the method is the best indicator of what you can do with that object. For example, if a method returns a pointer to anNSArray
object, you should not use this method to see if the array is mutable, as shown in the following code:
// DO NOT DO THIS! |
if ([myArray isKindOfClass:[NSMutableArray class]]) |
{ |
// Modify the object |
} |
If you use such constructs in your code, you might think it is alright to modify an object that in reality should not be modified. Doing so might then create problems for other code that expected the object to remain unchanged.
然后,什么是类簇呢?总结一下,不用到处去找了。
2.《Objective-C 2.0 Mac和iOS开发实践指南》中一段比较精辟的话:
实现为簇的一个类的init方法,用相应的具体子类的一个不同对象,替代了alloc所返回的对象。簇的alloc方法返回了属于特定的占位类的一个临时对象,init方法释放了该临时对象,并且返回了簇的具体子类之一的一个实例。这一后果有一个重要的隐含意义:一步应该保留alloc所返回的对对象的引用。将alloc和init编写为一条单个的嵌套语句。
3.cocoachina里有个帖子原帖地址,披麻皴回答的很好,可以看看加深记忆。
个人感觉,类簇就是一个可直接使用的抽象公共超类和多个不能直接使用的私有子类之间的种种。
(PS:有的类簇有两个或者更多公共超类)