假设我有一个NSDictionary的一个的NSArray和NSDictionary中的两个子集:基础目标-c:带数组的字典;用字典词典
NSMutableDictionary *mkDict(void){
NSMutableDictionary *dict=[NSMutableDictionary dictionary];
NSMutableDictionary *sub=[NSMutableDictionary dictionary];
NSMutableArray *array= [NSMutableArray array];
[dict setObject:array forKey:@"array_key"];
[dict setObject:sub forKey:@"dict_key"];
return dict;
}
有很多方法来访问子集的单个元素众多,而且我选择的时间其中三个。
第一种方式是通过访问父的键间接访问子元素:
void KVC1(NSMutableDictionary *dict, int count){
for(int i=0; i<count; i++){
char buf1[40], buf2[sizeof buf1];
snprintf(buf1,sizeof(buf1),"element %i", i);
snprintf(buf2, sizeof buf2, "key %i", i);
[[dict objectForKey:@"array_key"]
addObject:
[NSString stringWithUTF8String:buf1]];
[[dict objectForKey:@"dict_key"]
setObject:[NSString stringWithUTF8String:buf1]
forKey:[NSString stringWithUTF8String:buf2]];
}
}
第二个是使用的keyPath访问:
void KVC2(NSMutableDictionary *dict, int count){
for(int i=0; i<count; i++){
char buf1[40], buf2[sizeof buf1], buf3[sizeof buf1];
snprintf(buf1,sizeof(buf1),"element %i", i);
snprintf(buf2, sizeof buf2, "key %i", i);
snprintf(buf3, sizeof buf3, "dict_key.key %i",i);
[dict insertValue:
[NSString stringWithUTF8String:buf1]
atIndex:i inPropertyWithKey:@"array_key"];
[dict setValue:
[NSString stringWithUTF8String:buf1]
forKeyPath:
[NSString stringWithUTF8String:buf3]];
}
}
而第三,类似于首先是访问指向子元素的指针,然后使用该指针:
void KVC3(NSMutableDictionary *dict, int count){
NSMutableArray *subArray = [dict objectForKey:@"array_key"];
NSMutableDictionary *subDict = [dict objectForKey:@"dict_key"];
for(int i=0; i<count; i++){
char buf1[40], buf2[sizeof buf1];
snprintf(buf1,sizeof(buf1),"element %i", i);
snprintf(buf2, sizeof buf2, "key %i", i);
[subArray addObject:[NSString stringWithUTF8String:buf1]];
[subDict
setObject:
[NSString stringWithUTF8String:buf1]
forKey:
[NSString stringWithUTF8String:buf2]];
}
}
这里是时刻码:
#import <Foundation/Foundation.h>
#import <mach/mach_time.h>
// KVC1, KVC2 and KVC3 from above...
#define TIME_THIS(func,times) \
({\
mach_timebase_info_data_t info; \
mach_timebase_info(&info); \
uint64_t start = mach_absolute_time(); \
for(int i=0; i<(int)times; i++) \
func ; \
uint64_t duration = mach_absolute_time() - start; \
duration *= info.numer; \
duration /= info.denom; \
duration /= 1000000; \
NSLog(@"%i executions of line %i took %lld milliseconds", times, __LINE__, duration); \
});
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableDictionary *dict=mkDict();
NSMutableDictionary *dict2=mkDict();
NSMutableDictionary *dict3=mkDict();
TIME_THIS(KVC1(dict,1000),10);
TIME_THIS(KVC2(dict2,1000),10);
TIME_THIS(KVC3(dict3,1000),10);
if([dict isEqualToDictionary:dict2])
NSLog(@"And they are the same...");
[pool drain];
return 0;
}
下面是结果:
10 executions of line 256 took 57 milliseconds
10 executions of line 257 took 7930 milliseconds
10 executions of line 258 took 46 milliseconds
And they are the same...
问:为什么OS X雪豹/狮子建议使用KeyPaths所以臭慢的方法是什么?如果将count
的大小增加到10,000或更多,则KVC2在其他两种方法线性增加的情况下变得无限缓慢。
我做错了什么?访问字典中的子集合的单个元素是否有更好的习惯用法?
+1'它的名字应该是它表演的线索。“好笑! :-) – 2011-04-29 19:42:35