ObjC中怎么判断可变和不可变
怎么判断NSString和NSMutableString呢?
请听题
BOOL result = [@"123" isKindOfClass:[NSMutableString class]]; // A:YES B:NO
这很简单当然选B的,字符串常量是NSString。所以正确答案是A,是不是有种高考题的赶脚。建议这题出面试。
首先应该百度objc的类簇概念,然后是工厂模式。这篇笔记只讲怎么判断,开个传送门自己去打怪。
看控制台弄出来的结果
id str0 = [NSString alloc];//NSPlaceholderString->NSString id str1 = [[NSString alloc] init];//__NSCFConstantString->__NSCFString->NSMutableString->NSString id str3 = [NSString stringWithFormat:@"123"];//NSTaggedPointerString->NSString id str4 = [NSMutableString alloc];//NSPlaceholderMutableString->NSMutableString->NSString id str5 = [NSMutableString new];//__NSCFString->NSMutableString->NSString
字符串常量,也就是str1那种创建方式得到的类型是__NSCFConstantString并且明目张胆的是NSMutableString的子类。无论如何请勇敢的质疑苹果脑残的设计。并且后面的Array和Dictionary就不存在这种脑残的地方。我们无法知道到底黑盒子里有多少这种子类,根据倒推大法:
所以现在判断一个字符串是可变的这么写就行了
BOOL isMutable = [str isMemberOfClass:NSClassFromString(@"__NSCFString")];//请注意是isMemberOfClass:这个方法不要用成isKindOfClass:
把Array的控制台结果也弄出来简单的看一下
NSArray* arr0 = [[NSArray alloc] init];//__NSArray0->NSArray NSArray* arr1 = [NSArray arrayWithObject:@"123"];//__NSArrayI->NSArray NSMutableArray* arr3 = [[NSMutableArray alloc] init];//__NSArrayM->NSMutableArray->NSArray
可以发现虽然NSArray也子嗣众多,但不会出现String那种近亲乱的情况。
判断Array是不可变的这么写就行了,不需要写字符串的类型
BOOL notMutable = [arr isKindOfClass:[NSArray class]]&&![arr isKindOfClass:[NSMutableArray class]];
Dictionary的情况同NSArray。
转注出:原文