周末闲来无事,翻看到了自己以前在新浪博客上发的博文,真心吐槽新浪博客真不适合写技术贴(排版太丑 哈哈),索性今天就移到简书上来吧 ~ 知识点很简单,就是方便以后涉及到了便于查阅。废话不多说,开始动工~
在编程中经常需要列举collection中的元素,当前的Object-C语言有多种办法来实现循环遍历的功能.在此对这几种循环遍历总结了一下,希望对大家有所帮助.
1.for循环 基本遍历,功能有限.
NSArray *anyArr = @[@"1",@"2",@"3",@"4"];
for (int i = 0; i<anyArr.count; i++) {
id object = anyArr[i];
NSLog(@"-- %@ --",object);
}
//数组是‘有序的‘,字典 与 set 都是‘无序的’,
//需要先获取字典里的所有键 或是 set里的所有对象
NSDictionary *dic = @{@"name":@"Joeyoung", @"age":@"100", @"sex":@"man"};
NSArray *keyArr = [dic allKeys];
for (int i = 0; i<keyArr.count; i++) {
id key = keyArr[i];
id value =dic[key];
NSLog(@"-- %@ --",value);
}
NSSet *set = [NSSet setWithObjects:@"你",@"我",@"他",@"它",nil];
NSArray *setArr = [set allObjects];
for (int i = 0; i<setArr.count; i++) {
id object = setArr[i];
NSLog(@"-- %@ --",object);
}
2.使用 NSEnumerator 循环遍历
NSEnumerator 是抽象类,其中定义了两个方法,
供其子类实现:
//获取枚举中所有对象,以数组形式返回
@property (readonly, copy) NSArray<ObjectType> *allObjects;
//返回枚举中的下个对象,如果枚举中的全部对象都已返回,再次调用返回nil,表示到达枚举末端
- (nullable ObjectType)nextObject;
//NSArray
NSArray *anyArr = @[@"1",@"2",@"3",@"4"];
NSEnumerator *enumerator = [anyArr objectEnumerator];
id object;
while ((object = [enumerator nextObject]) != nil) {
NSLog(@"-- %@ --",object);
}
//NSDictionary
NSDictionary *dic = @{@"name":@"Joeyoung", @"age":@"100", @"sex":@"man"};
NSEnumerator *dicEnumerator = [dic keyEnumerator];
id key;
while ((key = [dicEnumerator nextObject]) != nil) {
id value = dic[key];
NSLog(@"-- %@ --",value);
}
//NSSet
NSSet *set = [NSSet setWithObjects:@"你",@"我",@"他",@"它",nil];
NSEnumerator *setEnumerator = [set objectEnumerator];
id setObject;
while ((setObject = [setEnumerator nextObject]) != nil) {
NSLog(@"-- %@ --",setObject);
}
3.快速遍历 (如果某个类的对象支持快速遍历,就可以宣称自己遵从名为 NSFastEnumeration 的协议)
//NSArray
NSArray *anyArr = @[@"1",@"2",@"3",@"4"];
for (id object in anyArr) {
NSLog(@"-- %@ --",object);
}
//NSDictionary
NSDictionary *dic = @{@"name":@"Joeyoung", @"age":@"100", @"sex":@"man"};
for (id key in dic) {
id value = dic[key];
NSLog(@"-- %@ --",value);
}
//NSSet
NSSet *set = [NSSet setWithObjects:@"你",@"我",@"他",@"它",nil];
for (id object in set) {
NSLog(@"-- %@ --",object);
}
//NSEnumerator 对象也实现了 NSFastEnumeration 协议,可以用来执行反向遍历
NSArray *any = @[@"1",@"2",@"3",@"4"];
for (id object in [any reverseObjectEnumerator]) {
NSLog(@"-- %@ --",object);
}
4.基于‘块’的遍历
//NSArray
/*
- (void)enumerateObjectsUsingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block
遍历是既能获取对象,也能获取对象对应的下标
*/
NSArray *anyArr = @[@"1",@"2",@"3",@"4"];
[anyArr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"-- %@ --",obj);
//可以设置中断遍历的条件
if (idx == 2) {
*stop = YES;
}
}];
//DSDictionary
/*
- (void)enumerateKeysAndObjectsUsingBlock:(void (NS_NOESCAPE ^)(KeyType key, ObjectType obj, BOOL *stop))block
*/
NSDictionary *dic = @{@"name":@"Joeyoung", @"age":@"100", @"sex":@"man"};
[dic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSLog(@"-- %@ --",obj);
if ([key isEqualToString:@"name"]) {
*stop = YES;
}
}];
//NSSet (NSOrderedSet 有序集合)
/*
- (void)enumerateObjectsUsingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, BOOL *stop))block
*/
NSSet *set = [NSSet setWithObjects:@"你",@"我",@"他",@"它",nil];
[set enumerateObjectsUsingBlock:^(id _Nonnull obj, BOOL * _Nonnull stop) {
NSLog(@"-- %@ --",obj);
}];
/**
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block
- (void)enumerateKeysAndObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(KeyType key, ObjectType obj, BOOL *stop))block
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, BOOL *stop))block
数组,字典,set都可以执行反向遍历。
只有在遍历数组或者是有序set等有顺序的collection时,上面的方法才有意义。
NSEnumerationOptions 是一个枚举类型
typedef NS_OPTIONS(NSUInteger, NSEnumerationOptions) {
//并发方式执行迭代,底层会通过GCD来处理并发执行事宜,此时执行顺序是’无序‘的
NSEnumerationConcurrent = (1UL << 0),
//反向遍历
NSEnumerationReverse = (1UL << 1),
};
*/
要点:
- 1.遍历collection有四种方式.最基本的办法是for循环,其次是NSEnumerator遍历法及快速遍历法,最新,最先进的方式则是"块枚举法";
- 2."块枚举法"本身能通过GCD来并发执行遍历操作,无须另行编写代码.而采用其他遍历方式则无法轻易实现这一点;
- 3.若提前知道待遍历的collection含有何种对象,则应该修改块签名,指出对象的具体类型.
千里之行,始于足下!
网友评论