在项目开发过程中数组是最常用到的,下面就来说下常见的几种数组遍历方法。
1. for 循环,也就是我们说的慢遍历
self.array = @[@"1",@"2",@"3",@"4",@"5",@"6"];
self.count = self.array.count;
for (NSInteger i = 0; i < self.count; i ++) {
NSLog(@"%@ ----- %@",self.array[i],[NSThread currentThread]);
}
2. for in ,也就是我们说的快遍历
for (NSString *str in self.array) {
NSLog(@"%@ ----- %@",str,[NSThread currentThread]);
}
3.NSEnumentor
NSEnumerator *enumer = [self.array objectEnumerator];
id obj;
while (obj = [enumer nextObject]) {
NSLog(@"%@ ----- %@",obj,[NSThread currentThread]);
}
4.block方式遍历
// 顺序遍历
[self.array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"%@ ----- %@",obj,[NSThread currentThread]);
}];
// 倒序遍历
[self.array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"%@ ----- %@",obj,[NSThread currentThread]);
}];
NSLog(@"end");
这里 *stop = NO 可以停止遍历。
以上四种遍历方式我们可以看出,都是在主线程中进行的,如果我们数组里面的操作非常耗就不适合用上面的方法了。我们知道手机的核是越来越多,所以我们需要充分利用iOS多核的作用,也就是我们经常用的GCD方法,利用GCD可以实现充分利用多核,并且随着手机不断升级,同样的代码,执行效率会自动提高。
5.快速迭代 dispatch_apply
// 快的原因:异步的并发的队列,自动开启子线程
dispatch_apply(self.count, dispatch_get_global_queue(0,0), ^(size_t index) {
NSLog(@"%@ ----- %@",self.array[index],[NSThread currentThread]);
});
NSLog(@"end");
从打印的结果可以看出,有的任务在主线程进行,有的任务在子线程进行。number = 1 表示主线程,其他表示子线程。
dispatch_apply 多线程同步循环,将block中的任务,逐个放到queue中,然后进行dispatch_sync执行,又因为dispatch_apply 是同步的,可以在主线程走任务。
如果我们想让遍历操作都在子线程中进行可以进行下面操作:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_apply(self.count, dispatch_get_global_queue(0, 0), ^(size_t index) {
sleep(1);
NSLog(@"%@ ----- %@",self.array[index],[NSThread currentThread]);
});
NSLog(@"end");
});
从结果可以看出,所有的操作都是在子线程中进行的。
除了上面的写法外,也可以这样实现:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
for (NSInteger i = 0; i < self.count; i++) {
NSLog(@"%ld",(long)i);
dispatch_group_async(group, queue, ^{
sleep(5);
NSLog(@"%ld -- %@",(long)i,[NSThread currentThread]);
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);// 等待queue任务执行完,才往下走;
dispatch_group_notify(group, queue, ^{ // 往下走,回调block
NSLog(@"group end");
});
// dispatch group 只能异步,并且不会在主线程走任务
dispatch_group_wait(group, DISPATCH_TIME_FOREVER) 表示只有group执行完之后才会继续往下面执行。