1)NSArray 和 NSSet 区别在containsObject这个函数的实现上就不一样,NSArray是循环去得到,NSSet是通过Key has表里面获取。
对于数组:
///GUNSTEP NSArray indexOfObject: 方法的实现
(BOOL)containsObject:(id)anObject {
return [self indexOfObject:anObject] != NSNotFound;
}-
(NSUInteger) indexOfObject: (id)anObject
{
unsigned c = [self count];if (c > 0 && anObject != nil)
{
unsigned i;
IMP get = [self methodForSelector: oaiSel];
BOOL (eq)(id, SEL, id)
= (BOOL ()(id, SEL, id))[anObject methodForSelector: eqSel];for (i = 0; i < c; i++) if ((*eq)(anObject, eqSel, (*get)(self, oaiSel, i)) == YES) return i;
}
return NSNotFound;
}
对于Set:
- (BOOL) containsObject: (id)anObject
{
return (([self member: anObject]) ? YES : NO);
}
//在 GSSet,m 里有对 member 的实现 - (id) member: (id)anObject
{
if (anObject != nil)
{
GSIMapNode node = GSIMapNodeForKey(&map, (GSIMapKey)anObject);
if (node != 0)
{
return node->key.obj;
}
}
return nil;
}
2)GCD 有可能发生死锁
for (int i = 0, i < 999; i++) {
dispatch_async(q,^{...});
}
dispatch_barrier_sync(q,^{...});
如果q 是一个主线的话可能会发生死锁了。
那么怎么办呢?
1,可以用dispatch_apply 函数:作用:该函数按指定的次数将指定的Block追加到指定的Dispatch Queue中,并等到全部的处理执行结束
dispatch_apply(999,q,^(size_t i){...});
2,使用信号源
define CONCURRENT_TASKS 4
dispatch_queue_t q = dispatch_queue_create("com.qiuxuewei.gcd", nil);
dispatch_semaphore_t sema = dispatch_semaphore_create(CONCURRENT_TASKS);
for (int i = 0; i < 999; i++) {
dispatch_async(q, ^{
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
性能优化:https://mp.weixin.qq.com/s/653JVbLJx3zIfBoxR9WXKw 写的好全。