OC foudation框架(下)的学习

news2024/11/18 19:45:53

OCfoudation框架(下)

前面学习了有关OCfoudation框架的部分内容,我们现在对于后面的内容继续学习。


文章目录

  • OCfoudation框架(下)
    • 数组(NSArray和NSMutableArray)
      • 对集合元素整体调用方法
      • 排序
      • 使用枚举器遍历元素
      • 快速枚举(for in)
      • 可变数组
    • 集合(NSSet 与 NSMutableSet)
      • 功能与用法
      • 判断元素重复的标准
      • NSMutableSet的功能和用法
      • NSCountedSet的用法
      • 有序集合
    • 字典
      • 功能和用法
      • 对key排序
      • 对key进行过滤
      • 用自定义类作为key
      • NSmutableDictionary

数组(NSArray和NSMutableArray)

创建数组的常见方法介绍:

  • arrary:创建一个不包含任何元素的空NSArray
  • arrayWithContentsOfFile:/initWithContentsOfFile:读取文件内容来创建
  • arrayWithObject:创建仅包含指定元素的NSArray
  • arrayWithObjects:创建包含指定的N个元素的NSArray;

下面我们通过一段代码来运用这个数组的一些方法。

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSArray* array = [NSArray arrayWithObjects:@"iOS", @"Android", @"Java讲义", @"Html", @"structs", @"nanxun", nil];
        NSLog(@"first: %@",[array objectAtIndex:0]);
        NSLog(@"last:%@", [array lastObject]);
        NSArray* arr1 = [array objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(2, 3)]];
        NSLog(@"%@",arr1);
        NSLog(@"Android:%ld", [array indexOfObject:@"Android"]);
        NSLog(@"Android in (2,5): %ld", [array indexOfObject:@"Android" inRange:NSMakeRange(2, 3)]);
        array = [array arrayByAddingObject:@"nannan"];
        array = [array arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:@"krystal", @"zitai", nil]];
        for (int i = 0; i < array.count; i++) {
            NSLog(@"%@", [array objectAtIndex:i]);
        }
        NSArray* arr2 = [array subarrayWithRange:NSMakeRange(5, 3)];
        [arr2 writeToFile:@"/Users/nanxun/Documents/testoc/foudation study/foudation study/myFile.txt" atomically:YES];
    }
    return 0;
}

打印结果如下:

在这里插入图片描述

接下来分析一下相关内容,先看我们在(2, 5)位置寻找Android的结果,发现他是一个数字9223372036854775807,这个数值实际上是NSNotFound这个常量的值,就下来我们通过两种方式在后面添加元素,arrayByAddingObject添加单个元素,arrayWithObjects方法是将一个数组中的元素全部追加到原数组后面。

同时可以看到,我门用程序直接输出数组的话,可知道中文无法正常输出,这个会转化成/U75af格式输出。

我们下面分析在NSArray中能否判断指定元素位于NSArray集合中的索引,我们的标准是什么?这个标准就是我们的isEqual: 方法,比较是否相同,为了理解这个部分的内容,我们建立一个FKUser来帮助自己理解相关内容。

接口部分

@interface FKUser : NSObject
@property (nonatomic, copy) NSString* name;
@property (nonatomic, copy) NSString* pass;
- (id) initWithName:(NSString*) aName pass:(NSString*) aPass;
- (void) say:(NSString*) content;
@end

实现部分

@implementation FKUser
- (id) initWithName:(NSString *)aName pass:(NSString *)aPass {
    if (self = [super init]) {
        self.name = aName;
        self.pass = aPass;
    }
    return self;
}
- (void) say:(NSString *)content {
    NSLog(@"%@说:%@", self.name, content);
}
- (BOOL) isEqual:(id)object {
    if (self == object) {
        return YES;
    }
    if ([object class] == [FKUser class]) {
        FKUser* target = (FKUser*) object;
        return [self.name isEqualToString:target.name] && [self.pass isEqualToString: target.pass];
    }
    return NO;
}
- (NSString*) description {
    return [NSString stringWithFormat:@"FKUser[_name = %@, _pass = %@]", self.name, self.pass];
}
@end

主函数部分

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSArray* array = [NSArray arrayWithObjects:
                          [[FKUser alloc] initWithName:@"sun" pass:@"123"],
                          [[FKUser alloc] initWithName:@"bai" pass:@"345"],
                           [[FKUser alloc] initWithName:@"zhu" pass:@"654"],
                            [[FKUser alloc] initWithName:@"tang" pass:@"178"],
                             [[FKUser alloc] initWithName:@"niu" pass:@"155"], nil];
        FKUser* newUser = [[FKUser alloc] initWithName:@"zhu" pass:@"654"];
        NSUInteger pos = [array indexOfObject:newUser];
        NSLog(@"newUser的位置为%ld", pos);
    }
    return 0;
}

输出结果为下:在这里插入图片描述

这里我们发现了一个事情就是我们重新创建了一个对象,虽然该对象与集合中的任何对象都不相同,但是我们的程序还是可以返回该FKUser对象在该集合中的索引,这是因为他调用的是我们的isEqual方法

对集合元素整体调用方法

如果只是简单的调用集合元素的方法,主要有两种方法:

  • makeObjectPerformSelector:依次调用NSArray集合中每个元素的指定方法需要传入一个SEL参数
  • makeObjectsPerformSelcetor:withObject:一次调用集合中每个元素的指定方法,该方法第一个参数SEL用于指定调用那个方法,第二个参数用于调用集合元素方法时候传入参数;第三参数用来控制是否终止迭代,如果在处理某个元素后,将第三个元素复制为YES,该方法就终止迭代调用。

如果希望对集合中所有元素进行隐式遍历,并使用集合元素来执行某一段代码,可以使用以下三种方式

  • enumerateObjectUsingBlock: 遍历集合中的所有元素,并依次使用元素来执行指定的代码块
  • enumerateObjectsWithOptions:usingBolck: 和上面的差别就是可以传入一个号控制遍历的选项。
  • enumerateObjectAtIndexes:options:usingBlock: 这个它增加了一个遍历指定范围内的元素,并一次使用元素来执行指定的代码块。
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSArray* array = [NSArray arrayWithObjects:
                          [[FKUser alloc] initWithName:@"sun" pass:@"123"],
                          [[FKUser alloc] initWithName:@"bai" pass:@"345"],
                           [[FKUser alloc] initWithName:@"zhu" pass:@"654"],
                            [[FKUser alloc] initWithName:@"tang" pass:@"178"],
                             [[FKUser alloc] initWithName:@"niu" pass:@"155"], nil];
        [array makeObjectsPerformSelector:@selector(say:) withObject:@"下午好,NSArray真强大"];
        NSString* content = @"疯狂iOS讲义";
        [array enumerateObjectsAtIndexes: [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(2, 2)]options:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            NSLog(@"正在处理第%ld个元素,%@",idx, obj);
            [obj say:content];
        }];
    }
    return 0;
}

打印结果如下:

在这里插入图片描述

这两段代码,主要调用了两个函数,一个是调用了**makeObjectsPerformSelector:**方法通过withObjects为say方法传入参数.

第二个则是应用了enumerateObjectsAtIndexes:options:usingBlock:方法并用这些元素来这些指定的代码块,传入的代码块参数就代表程序对每个集合元素迭代执行的代码体。(笔者这里对与Block不了解,还需要后续学习进行补充)。

排序

对数组的排序函数主要有三种:

  • sortedArrayUsingFunction:contes:该方法使用排序函数对集合元素进行一个排序,该排序函数必须返回NSOrderedDesceding,NSOrderedAscending,NSOrderedSame三个枚举常量。
  • sortedArrayUsingSelector:该方法使用集合元素自身的方法对集合元素进行排序,它的排序函数同样会返回上面给出的三个枚举值。
  • sortedArrayUsingComparator:该方法使用代码块对与集合元素进行排序

三种方法的返回值都是一个排好序的NSArray对象。

下面演示一下我们对于NSArray集合元素进行一个排序。

NSInteger inSort (id num1, id num2, void* context) {
    int v1 = [num1 intValue];
    int v2 = [num2 intValue];
    if (v1 < v2) {
        return NSOrderedAscending;
    } else if (v1 == v2) {
        return NSOrderedSame;
    } else {
        return NSOrderedDescending;
    }
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSArray* array1 = [NSArray arrayWithObjects:@"C++",@"Python",@"Perl",@"C",@"Objective-C",@"Ruby", nil];
        array1 = [array1 sortedArrayUsingSelector:@selector(compare:)];
        NSLog(@"%@", array1);
        NSArray* array2 = [NSArray arrayWithObjects:[NSNumber numberWithInt:20], [NSNumber numberWithInt:12], [NSNumber numberWithInt:-8],[NSNumber numberWithInt:50], [NSNumber numberWithInt:19],nil];
        array2 = [array2 sortedArrayUsingFunction:inSort context:nil];
        NSLog(@"%@", array2);
        NSArray* array3 = [array2 sortedArrayUsingComparator:^(id obj1, id obj2) {
            if ([obj1 intValue] > [obj2 intValue]) {
                return NSOrderedDescending;
            } else if ([obj1 intValue] < [obj2 intValue]) {
                return NSOrderedAscending;
            } else {
                return NSOrderedSame;
            }
        }];
        NSLog(@"%@", array3);
    }
    return 0;
}

打印结果如下:

在这里插入图片描述

在上述代码中间我们示范了三种对于NSArrary进行排序的三种方法,第一种是调用NSString自身的compaer:方法进行排序(compare的比较和成语言中的strcmp()函数相似)。

后面是两种不同的方法,一个是调用代码块,一个是调用函数的方法。

使用枚举器遍历元素

我们有两个方法获得枚举器

  • objectEnumerator:正序遍历
  • reverseObjectEnumerator:逆序遍历

枚举器的方法有以下两个

  • allObjects:获取枚举集合中所有的元素
  • reverseObjectEnumerator:获取被枚举集合中的下一个元素。
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSArray* array1 = [NSArray arrayWithObjects:@"C++",@"Python",@"Perl",@"C",@"Objective-C",@"Ruby", nil];
        NSEnumerator* en = [array1 objectEnumerator];
        id object;
        while (object = [en nextObject]) {
            NSLog(@"%@", object);
        }
        NSLog(@"");
        NSEnumerator* an = [array1 reverseObjectEnumerator];
        while (object = [an nextObject]) {
            NSLog(@"%@", object);
        }
        
    }
    return 0;
}

打印结果为:

在这里插入图片描述

一种是升序,另一种是降序。

快速枚举(for in)

快速枚举的语法格式如下:

for(type variableName in collection) {
  //variableName自动迭代访问每一个元素
}

tips:这里面如果用快速枚举来遍历NSDictionary对象的时候,它代表的是key值

下面给出一个示范

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSArray* array1 = [NSArray arrayWithObjects:@"C++",@"Python",@"Perl",@"C",@"Objective-C",@"Ruby", nil];
        for (id object in array1) {
            NSLog(@"%@", object);
        }
        
    }
    return 0;
}

打印结果如下

在这里插入图片描述

可变数组

NSArray代表元素不可变的集合,一旦创建成功,程序不能向集合调价新的元素,这时候我们就要运用到我们的NSMutableArray.

它给出了增加(add),删除(remove),替换(replace)元素的方法。

NSMutableArray还提供了sortUsingSelector:、sortUsingComparator:、sortUsingFunction: context:方法,它们与前面介绍的NSArray的排序的方法类似,区别是NSArray的排序的方法返回的是一个新的NSArray对象,而NSMutableArray返回的是排序后的原来的对象。

下面给出代码示范

NSString *NSCollectionToString(NSArray *array) { // 将集合中的所有元素合成一个字符串便于我们打印
    NSMutableString *result = [NSMutableString stringWithString:@"["];
    for (id obj in array) {
        [result appendString: [obj description]];
        [result appendString:@","];
    }
    NSUInteger len = [result length];
    [result deleteCharactersInRange:NSMakeRange(len - 1, 1)];//去掉最后一个字符
    [result appendString:@"]"];
    return result;
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSMutableArray* array1 = [NSMutableArray arrayWithObjects:@"C++",@"Python",@"Perl",@"C",@"Objective-C",@"Ruby", nil];
        [array1 addObject:@"Java"];
        NSLog(@"%@", NSCollectionToString(array1));
        [array1 addObjectsFromArray:[NSArray arrayWithObjects:@"Js", @"Ts", nil]];
        NSLog(@"%@", NSCollectionToString(array1));
        [array1 insertObject:@"Android" atIndex:2];
        NSLog(@"%@", NSCollectionToString(array1));
        [array1 insertObjects:[NSArray arrayWithObjects:@"web",@"server", nil] atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(3, 2)]];
        NSLog(@"%@", NSCollectionToString(array1));
        [array1 removeLastObject];
        NSLog(@"%@", NSCollectionToString(array1));
        [array1 removeObjectAtIndex:5];
        NSLog(@"%@", NSCollectionToString(array1));
        [array1 replaceObjectAtIndex:2 withObject:@"疯狂iOS"];
        NSLog(@"%@", NSCollectionToString(array1));
    }
    return 0;
}

打印结果如下:

在这里插入图片描述

集合(NSSet 与 NSMutableSet)

NSSet集合不允许包含相同的元素(它没有明显的顺序),如果试图将两个相同的元素放在同一个NSSet集合中,则只会保留一个元素

功能与用法

实际上,NSArray与NSSet依然有大量的相似之处。

  • 都可以通过count方法获取集合元素数量
  • 可以用快速枚举遍历集合元素
  • 可以通过objectEnumerator方法获取NSEnumerator枚举器对集合元素遍历。
  • 提供了makeObjectsPerformSelector:方法对集合元素真题调用某个方法

接下来我们介绍一下NSSet的常用方法

  • setByAddingObject:向集合中添加一个新元素,返回添加元素后的新集合
  • setByAddingObjectsFromSet:使用NSSet集合向集合中添加多个新元素,返回新集合
  • setByAddingObjectsFromArray:使用NSArray集合向集合中添加多个新元素,返回新集合
  • allObjects:返回集合中所有元素组成的NSArray
  • anyObject:返回集合中的某个元素。(但是并不保证随机返回集合元素)。
  • containsObject:判断集合是否包含指定元素
  • Member:判断该集合是否包括与该参数相等的元素,如果包含就返回相等的元素,反之则返回nil。
  • objectsPassingTest:需要传入一个代码块对集合元素进行一个过滤,满足该代码块的集合元素会被保留下来并组成一个新的NSSet集合作为返回值
  • objectsWithOptions:passingTest:和前一个方法的功能基本相似,只是可以额外地传入一个NSEnumerationOptions作为迭代参数
  • isSubsetOfSet:判断是否为一个子集
  • intersectsSet:判断是否有交集
  • isEqualToset:判断集合是否相同

下面给出一段代码来理解相关内容

NSString *NSCollectionToString(id array) {
    NSMutableString *result = [NSMutableString stringWithString:@"["];
    for (id obj in array) {
        [result appendString: [obj description]];
        [result appendString:@","];
    }
    NSUInteger len = [result length];
    [result deleteCharactersInRange:NSMakeRange(len - 1, 1)];//去掉最后一个字符
    [result appendString:@"]"];
    return result;
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSSet* set1 = [NSSet setWithObjects:@"iOS", @"Andirod",@"web",@"server", nil];
        NSLog(@"set个数为%ld", [set1 count]);
        NSLog(@"%@", NSCollectionToString(set1));
        NSSet* set2 = [NSSet setWithObjects:@"krystal",@"xiyang",@"fenfneko",@"web", nil];
        NSLog(@"%@", NSCollectionToString(set2));
        set1 = [set1 setByAddingObject:@"shenyi"];
        NSSet* s1 = [set1 setByAddingObjectsFromSet:set2];
        NSLog(@"并集合%@", NSCollectionToString(s1));
        BOOL bo = [set2 isSubsetOfSet: set1];
        NSLog(@"set2是否是set1子集集%ld",bo);
        BOOL bb = [set1 containsObject:@"Andirod"];
        NSLog(@"是否包含Andirod:%ld", bb);
        NSLog(@"从set1中取出一个%@",[set1 anyObject]);
        NSSet* fileteredSet = [set1 objectsPassingTest:^(id obj, BOOL *stop) {
            return (BOOL)([obj length] > 3);
        }];
        NSLog(@"set1中元素长度大于8的集合元素有%@",NSCollectionToString(fileteredSet));
        
    }
    return 0;
}

下面是代码的结果:

在这里插入图片描述

这部分内容主要是一个演示相关代码的一个作用。

判断元素重复的标准

这里涉及到了一个Hash表的内容,我们每存入一个元素那么我们的NSSet会带调用该对象的一个Hash方法来计算一个Hash值,然后根据HashCode计算出元素在底层Hash表中的存储位置。如果出现了两个元素通过了isEqual方法但是它俩的值相同,那么我们这里的方式是通过链表将这两个元素连接起来。

这里我们就可以知道NSSet中判断两个元素是否相等的标准如下:

  • 两个对象通过isEqual的方法返回YES
  • 两个对象的hash方法的返回值也相等
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSSet* array = [NSSet setWithObjects:
                                  [[FKUser alloc] initWithName:@"sun" pass:@"123"],
                                  [[FKUser alloc] initWithName:@"bai" pass:@"345"],
                                   [[FKUser alloc] initWithName:@"zhu" pass:@"123"],
                                    [[FKUser alloc] initWithName:@"tang" pass:@"178"],
                                     [[FKUser alloc] initWithName:@"niu" pass:@"155"], nil];
        NSLog(@"元素个数为%ld", [array count]);
        NSLog(@"%@", NSCollectionToString(array));
    }
    return 0;
}

这是我们之前用过的FKUser类别,我们在这个类别中间定义了我们的isEqual:方法它只要name和oass相同就说明了我们的两个对象是相同的。但是打印结果却不符合我们的一个预期

在这里插入图片描述

发现出现了两个相同的元素,因此我们要重写一下Hash方法。

- (NSUInteger) hash {
    NSLog(@"===hash===");
    NSUInteger nameHash = _name == nil ? 0 : [_name hash];
    NSUInteger passHash = _pass == nil ? 0 : [_pass hash];
    return nameHash * 31 + passHash;
}

修改之后发现结果就恢复正常了。

在这里插入图片描述

这里我们发现了我们执行了5次Hash方法,这一步说明我们每次添加一个集合与安素,总是会先调用该元素的Hash方法,在重写这两种方法的时候,我们的目的主要是为了满足NSSet的性质,为了保证哦我们的NSSet保持一个较高的性能。

tips:Hash方法对于NSSet是非常重要的,下面给出重写Hash方法的基本原则。

  • 同一对象返回的Hash值应该是相同的
  • isEqual:方法比较返回YES的时候,这两个对象的Hash应返回相等的值·
  • 对象中所有被isEqual比较标准的实例变量都应该用来就算hashCode值。

一般情况我们的返回值都写成[f1 hash] * (质数) + [f2 hash]

NSMutableSet的功能和用法

和array相似,add(增加),remove(删除)。

主要要记住交,并,交,差集的函数

  • unionSet:计算并集
  • minusSet:计算差集
  • intersectSet:计算交集
  • setSet:用后一个元素替换已有集合中的所有元素
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSMutableSet* set1 = [NSMutableSet setWithCapacity:10];
        [set1 addObject:@"Java"];
        NSLog(@"add a one %@",NSCollectionToString(set1));
        [set1 addObjectsFromArray:[NSArray arrayWithObjects:@"krystal",@"xiyang",@"zzr", nil]];
        NSLog(@"add many %@", NSCollectionToString(set1));
        [set1 removeObject:@"xiyang"];
        NSLog(@"remove one %@",NSCollectionToString(set1));
        NSMutableSet* set2 = [NSSet setWithObjects:@"fenfenko",@"shenyi", nil];
        //[set1 unionSet: set2];
        //[set1 minusSet: set2];
        //[set1 intersectSet:set2];
        [set1 setSet:set2];
        NSLog(@"%@", NSCollectionToString(set1));
    }
    return 0;
}

打印结果如下:

在这里插入图片描述

NSCountedSet的用法

NSCountedSet主要是有一个特色就是它会为每一个元素增加一个该元素出现的个数,我们可以不可以添加元素,但是如果我们添加的元素重复了,但是会将该元素的添加次数加1.删除元素的时候也是将这个元素添加次数减1,知道它为0的时候,这个元素才会真正的从NSCountedSet中删除。

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSCountedSet* set1 = [NSCountedSet setWithObjects:@"iOS讲义",@"Android",@"Java", nil];
        [set1 addObject:@"Java"];
        [set1 addObject:@"Java"];
        NSLog(@"%@", NSCollectionToString(set1));
        NSLog(@"Java的添加次数为%ld", [set1 countForObject:@"Java"]);
        [set1 removeObject:@"Java"];
        NSLog(@"%@", NSCollectionToString(set1));
        NSLog(@"Java的添加次数为%ld", [set1 countForObject:@"Java"]);
        [set1 removeObject:@"Java"];
        [set1 removeObject:@"Java"];
        NSLog(@"%@", NSCollectionToString(set1));
        NSLog(@"Java的添加次数为%ld", [set1 countForObject:@"Java"]);
    }
    return 0;
}

打印结果为:

在这里插入图片描述

这里就很好的体现了我们的NSCountedSet的特色。

有序集合

NSOrderedSet最主要的点在于可以保持与安素的添加顺序,而且每一个元素都有缩影,可以根据缩影来操作元素。

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSOrderedSet* set = [NSOrderedSet orderedSetWithObjects:[NSNumber numberWithInt:40],[NSNumber numberWithInt:12],[NSNumber numberWithInt:-9],[NSNumber numberWithInt:20], nil];
        NSLog(@"first :%@", [set firstObject]);
        NSLog(@"last:%@", [set lastObject]);
        NSLog(@"索引为2的元素:%@", [set objectAtIndex:2]);
        NSIndexSet* indexSet = [set indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL* stop) {
            return (BOOL)([obj intValue] > 10); // 返回大于10的值
        }];
        NSLog(@"%@", indexSet);
    }
    return 0;
}

请添加图片描述

字典

这里的字典和C++中的map大致相同,它拥有一个键值对,所有key放在一个Set集合中,但是如果我们采用一个allKeys方法来返回却是一个NSArray。

功能和用法

初始化方法:一般以dictionary开头

在这里插入图片描述

访问方式:

请添加图片描述

@implementation NSDictionary (print)
- (void)print {
    NSMutableString* result = [NSMutableString stringWithString:@"["];
    for (id key in self) {
        [result appendString:[key description]];
        [result appendString:@"="];
        [result appendString:[self[key] description]];
        [result appendString:@", "];
    }
    NSUInteger len = [result length];
    [result deleteCharactersInRange:NSMakeRange(len - 1, 1)];
    [result appendString:@"]"];
    NSLog(@"%@", result);
}

这段代码演示了两种经典的语法,通过key获取value值 self[key]

下面给出一段代码来演示相关内容。

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:[[FKUser alloc] initWithName:@"krystal" pass:@"24"], @"one", [[FKUser alloc] initWithName:@"xiyang" pass:@"33"], @"two",[[FKUser alloc] initWithName:@"flandre" pass:@"111"], @"three", [[FKUser alloc] initWithName:@"fenfenko" pass:@"2222"], @"four",[[FKUser alloc] initWithName:@"krystal" pass:@"24"], @"five", nil];
        [dict print];
        NSLog(@"有多少个key-value对:%ld", [dict count]);
        NSLog(@"dict的所有key为%@", [dict allKeys]);
        NSLog(@"krystal对应的所有key为%@", [dict allKeysForObject:[[FKUser alloc] initWithName:@"krystal" pass:@"24"]]);
        NSEnumerator* en = [dict objectEnumerator];
        NSObject* value;
        while (value = [en nextObject]) {
            NSLog(@"%@", value);
        }
        [dict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL* stop) {
            NSLog(@"key的值为:%@",key);
            [value say:@"101牛逼"];
        }];
        
    }
    return 0;
}

请添加图片描述

请添加图片描述

这里就演示了我们的dictionary的相关的代码演示。

对key排序

他和对于数组的排序一样,都是类似的,它的返回值同样是那三个关键字:NSOrderedAscendingNSOrderedDescendingNSOrderedSame

接下来示范一下排序。

NSString *NSCollectionToString(id array) {
    NSMutableString *result = [NSMutableString stringWithString:@"["];
    for (id obj in array) {
        [result appendString: [obj description]];
        [result appendString:@","];
    }
    NSUInteger len = [result length];
    [result deleteCharactersInRange:NSMakeRange(len - 1, 1)];//去掉最后一个字符
    [result appendString:@"]"];
    return result;
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:@"iOS",@"one",@"Android",@"two",@"Java",@"three",@"Objective-c",@"four", nil];
        [dict print];
        NSArray* keyArr1 = [dict keysSortedByValueUsingSelector:@selector(compare:)];
        NSLog(@"%@", keyArr1);
        NSArray* keyArr2 = [dict keysSortedByValueUsingComparator:^(id value1, id value2) {
            if ([value1 length] > [value2 length]) {
                return NSOrderedDescending;
            } else if ([value1 length] == [value2 length]) {
                return NSOrderedSame;
            } else {
                return NSOrderedAscending;
            }
        }];
        NSLog(@"%@", keyArr2);
        
    }
    return 0;
}

打印结果如下

请添加图片描述

对key进行过滤

  • keysOfEntriesPassingTest:使用代码块迭代处理key-value对,只有符合代码块条件的会留下来。一共接收三个参数,第一个是正在迭代处理的key,第二个参数代表正在迭代处理的value,第三个参数代表是是否需要继续迭代,如果第三个参数设置成NO,这个方法就会立即停止迭代。
  • keysOfEntriesWithOptions:passingTest:该方法的功能和前一个方法的功能基本相同,可以额外传入一个附加的NSEnumerationOptions的选项参数。
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:89], @"Objective-C",[NSNumber numberWithInt:69], @"Ruby",[NSNumber numberWithInt:75], @"Python",[NSNumber numberWithInt:109], @"Prel", nil];
        [dict print];
        NSSet* keySet = [dict keysOfEntriesPassingTest:^(id key, id value, BOOL* stop) {
            return (BOOL)([value intValue] > 80);
        }];
        NSLog(@"%@", keySet);
    }
    return 0;
}

打印结果如下:

请添加图片描述

用自定义类作为key

我们可以用自己定义的类来作为key,但是要满足两个要求:

  • 正确重写isEqual:方法和hash方法
  • 自定义类实现了copyWithZone:方法,最好可以返回对象的不可变副
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        FKUser* u1 = [[FKUser alloc] initWithName:@"krystal" pass:@"24"];
        NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
                              @"one", [[FKUser alloc] initWithName:@"xiyang" pass:@"23"],
                              @"two", [[FKUser alloc] initWithName:@"flandre" pass:@"22"],
                              @"three", [[FKUser alloc] initWithName:@"xiyang" pass:@"23"],
                              @"four", [[FKUser alloc] initWithName:@"fenfenko" pass:@"19"],
                              @"five", [[FKUser alloc] initWithName:@"niu" pass:@"155"],
                              @"six", u1, nil];
        u1.pass = nil;
        [dict print];
    }
    return 0;
}

打印结果如下:

请添加图片描述

这里我们可以看到它会让重复的key出现一次。

NSmutableDictionary

它其实也主要是提供了可以增加key-value对,和删除key-value对的一系列方法

请添加图片描述

代码演示

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"iOS", @"99", nil];
        dict[@"99"] = @"iOSS";
        [dict print];
        dict[@"Android"] = @"ddd";
        [dict print];
        NSDictionary* dict2 = [NSDictionary dictionaryWithObjectsAndKeys:@"Java", @"sss", @"python", @"struct", nil];
        [dict addEntriesFromDictionary:dict2];
        [dict print];
        [dict removeObjectForKey:@"sss"];
        [dict print];
    }
    return 0;
}

打印结果如下:

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1662252.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

idea-自我常见配置

1. 主题配置 2. 显示方法分隔符 Editor->General->Appearance 3. 忽略大小写提示 Editor->General->Code Completion 4. 自动导包 Editor->general->Auto Import 5. 取消单行显示Tabs Editor->General->Editor Tabs 效果如下图&#xff1a; 6. 设置…

Vue项目npm install certificate has expired报错解决方法

1.Vue项目 npm install 安装依赖突然报错&#xff1a; npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/zrender/download/zrender-4.3.0.tgz failed, reason: certificate has expired npm ERR! A com…

Neo4j 之安装和 CQL 基本命令学习

正常使用结构化的查询语言 SQL&#xff08;Structured Query Language&#xff09;较多一些&#xff0c;但是像 Neo4j 这种非结构化的图形数据库来说&#xff0c;就不得不学习下 CQL&#xff08;Cypher Query Language&#xff09;语言了。如果你之前学过 《离散数学》或《图论…

Navicat 17 的数据分析

上周的博客预告了 Navicat 17&#xff08;英文版&#xff09;即将发布&#xff0c;目前正在测试阶段&#xff0c;并计划于 5 月 13 日发布。如我们所见&#xff0c;版本 17 推出了众多令人兴奋的新功能。其中最大亮点是数据分析工具&#xff0c;只需点击按钮&#xff0c;即可为…

phpmyadmin配置文件权限错误

错误信息 配置文件权限错误,不应任何用户都能修改! 解决办法 找到phpmyadmin所在目录 给phpmyadmin目录授权755 chmod -R 755 phpmyadmin验证服务是否可以正常访问

Unity使用ToggleGroup对多个Toggle进行管理时,初始化默认选项失效的问题

问题描述&#xff1a; 在unity脚本的OnEnable中用代码设置Toggle集合中的其中一个对象的ison时&#xff0c;发现并没有根据设置发生变化。但是该Toggle的OnValueChange却发生过变化。 如果使用协程等待0.01s,那么对应组件的ison的修改才能生效&#xff0c;但是逐帧分析的话会发…

mysql 细分

索引选择性 索引列的唯一值数量 / 表中的总行数 mysql如何优化-CSDN博客 批量问题 批处理默认是逐条发送 SQL 到数据库的&#xff0c;没有充分利用数据库提供的原生批处理能力&#xff0c;需要额外的配置来启用真正的批处理支持&#xff0c;如使用ExecutorType.BATCH 自定…

​​​【收录 Hello 算法】第 5 章 栈与队列

第 5 章 栈与队列 Abstract 栈如同叠猫猫&#xff0c;而队列就像猫猫排队。 两者分别代表先入后出和先入先出的逻辑关系。 本章内容 5.1 栈5.2 队列5.3 双向队列5.4 小结

前端Vue uView 组件<u-search> 自定义右侧搜索按钮样式

前言 uView 文档的效果不是ui设计的样式 需要重新编辑 原效果 ui设计效果 解决方案 设置里说明的需要传一个样式对象 这个对象 需要写在 script 标签里面 这里需要遵循驼峰命名 比如font-size 改为 fontSize lineHeight和textAlign为水平锤子居中效果 searchStyle: {ba…

k8s安装nginx Ingress超详细指南

在本全面的 Ingress 指南中&#xff0c;您将学习如何在 Kubernetes 上设置 Nginx Ingress控制器并使用 DNS 配置 Ingress。 目前有两种 Nginx Ingress 控制器。 kubernetes 社区的 Nginx Ingress 控制器Nginx Inc 开发的 Nginx Ingress 控制器 我们将使用 Kubernetes 社区 N…

【Qt 学习笔记】Qt常用控件 | 多元素控件 | Table Widget的说明及介绍

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 多元素控件 | Table Widget的说明及介绍 文章编号&#…

内存拆解分析表:学习版[图片]

对拆解system中主要是对比测试机和对比机之间的差距&#xff0c;测试机那些地方高于对比机 拆解表&#xff0c;作为理解 在拆解表中system测试机比对比机多出113M 这说明是有问题的 对system拆解&#xff1a; system12345对比机9102294380941069391081628测试机10252010331…

腾讯云服务器部署前后端服务

服务器&#xff1a;OpenCloudOS &#xff08;兼容centos8&#xff09; 后端&#xff1a;javaSpringboot 前端&#xff1a;Vue 下载jdk 1&#xff09;下载jdk11 wget https://download.java.net/openjdk/jdk11/ri/openjdk-1128_linux-x64_bin.tar.gz 2&#xff09;解压jdk …

uni-appH5Android混合开发二 || 使用Android Studio打包应用APK

前言&#xff1a; 在上一章节我们已经讲了如何uni-app离线打包Android平台教程&#xff0c;这一章就该来讲讲如何使用Android Studio打包应用APK提供给Android手机安装使用了。 uni-app跨平台框架介绍和快速入门 uni-app跨平台框架介绍和快速入门 第一步、首先打开已经编译好的…

Element快速上手!

Element是饿了么公司前端团队开发的一套基于Vue的组件库&#xff0c;用于快速构建网页~ 官网链接&#xff1a; Element - The worlds most popular Vue UI frameworkElement&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库https://element.elem…

uni-app(三):离线打包与插件引用(Android)

离线打包与插件引用 1.下载Android离线SDK2.使用Android Studio打开离线打包项目并更新Gradle3.解决报错4.构建5.配置AppKeya.查看证书b.申请AppKeyc.配置AppKey 6.生成本地打包App资源7.拷贝App资源到Android项目中8.修改 appid9.修改Android项目配置文件10.下载证书并配置11.…

基于Springboot+Vue的Java项目-电影院购票系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员衣一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

开源高性能的分布式时序数据库:Lindb

Lindb&#xff1a;为大数据时代量身打造的高性能时序数据库&#xff0c;让海量数据存储与实时分析触手可及。- 精选真开源&#xff0c;释放新价值。 概览 Lindb 是一款开源的分布式时序数据库&#xff0c;它以其高性能和可伸缩性在海量数据存储及快速查询计算方面展现出独特的…

在数字化时代保持企业财务管理的持续技术创新

根据全球市场调查&#xff0c;在现阶段企业如果还不更新自身的商业运作模式&#xff0c;企业的业务可能会一点一点丧失市场竞争力。技术进步是所有行业发展的明显趋势。许多年轻的初创企业具有创新管理思维、精益求精的决策流程和现代化的商业基础设施&#xff0c;这些顺应时代…

uniapp百度地图聚合

// loadBMap.js ak 百度key export default function loadBMap(ak) {return new Promise((resolve, reject) > {//聚合API依赖基础库,因此先加载基础库再加载聚合APIasyncLoadBaiduJs(ak).then(() > {// 调用加载第三方组件js公共方法加载其他资源库// 加载聚合API// Ma…