【iOS】—— Foundation框架(二)- 数组(NSArray与NSMutableArray)

7.4 Objective-C集合概述

Objective-C集合类是一个工具类,它可以用于存储数量不等的多个对象,并可以实现常用的数据结构,如栈、队列等。

Objective-C集合的分类:

34

集合类(容器类)

为了保存数量不确定的数据,以及保存具有映射关系的数据(也被称为关联数组),Objective-C提供了集合类,主要负责保存其他数据。
数组元素既可以是基本类型的值,也可以是对象(实际上保存的是对象的指针变量);而集合里只能保存对象(实际上只是保存对象的指针变量,但通常认为集合里保存的是对象)。

三种集合示意图:

4

  • NSSet集合类似于于一个罐子,把一个对象添加到NSSet集合时,NSSet集合无法记住添加这个元素的顺序,所以NSSet里的元素不能重复(否则系统无法精确的识别这个元素)。只能根据元素本身来访问(这也是NSSet集合里元素不允许重复的原因)
  • NSArray集合非常像一个数组,它可以记住每次添加元素的顺序,只是NSMutableArray的长度可变。可以直接根据元素的索引来访问
  • NSDictionary集合也像一个罐子,只是它里面的每项数据都由两个值组成。可以根据每项元素的key值来访问其value

7.5 数组(NSArray与NSMutableArray)

NSArray代表有序、可重复的一个集合,集合中每个元素都有其对应的顺序索引。


7.5.1 NSArray的功能与用法

NSArray提供了类方法和实例方法来创建NSArray,类方法以array开始,而实例方法以init开始。

创建NSArray对象的常见方法:
  • array:创建一个不包含任何元素的空的NSArray。
  • arrayWithContentsOfFile:/initWithContentsOfFile::读取文件内容来创建NSArray。
  • arrayWithObject:/initWithObject::创建只包含指定元素的NSArray。
  • arrayWithObjects:/initWithObjects::创建包含指定的N个元素的NSArray。
NSArray集合的常用方法:
  • 查询集合元素在NSArray中的索引。
  • 根据索引值取出NSArray集中的元素。
  • 对集合元素整体调用方法。
  • 对NSArray集合进行排序。
  • 取出NSArray集合中的部分集合组成新集合。
NSArray常规用法:
        NSArray* array = [NSArray arrayWithObjects:
                          @"疯狂iOS讲义", @"疯狂Android讲义",
                          @"疯狂Ajax讲义", @"疯狂XML讲义",
                          @"Struts 2.x权威指南", nil];
        NSLog(@"第一个元素:%@", [array objectAtIndex:0]);
        NSLog(@"索引为1的元素:%@", [array objectAtIndex:1]);
        NSLog(@"最后一个元素:%@", [array lastObject]);
        //获取索引从2~5的元素组成的新集合
        NSArray* arr1 = [array objectsAtIndexes:[NSIndexSet
                                                 indexSetWithIndexesInRange:NSMakeRange(2, 3)]];
        NSLog(@"%@", arr1);
        //获取元素在集合中的位置
        NSLog(@"疯狂Android讲义的位置为:%ld",
              [array indexOfObject:@"疯狂Android讲义"]);
        //获取元素在集合指定范围中的位置
        NSLog(@"在2~5范围疯狂Android讲义的位置为:%ld",
              [array indexOfObject:@"疯狂Android讲义" inRange:NSMakeRange(2, 3)]);
        //向数组的最后追加一个元素
        //原NSArray本身并没有改变,只是将新返回的NSArray赋给array
        array = [array arrayByAddingObject:@"孙悟空"];
        //向array数组的最后追加另一个数组的所有元素
        //原NSArray本身并没有改变,只是将新返回的NSArray都追加给array
        array = [array arrayByAddingObjectsFromArray:
                 [NSArray arrayWithObjects:@"宝玉", @"黛玉", nil]];
        for (int i = 0; i < array.count; i++) {
            NSLog(@"%@", [array objectAtIndex:i]);
            //上面代码也可简写为:
            //NSLog(@"%@", array[i]);
        }
        //获取array数组中索引为5~8处的所有元素
        NSArray* arr2 = [array subarrayWithRange:NSMakeRange(5, 3)];
        //将NSArray集合的元素写入文件“myFile.txt”
        [arr2 writeToFile:@"myFile.txt" atomically:YES];

输出结果为:
45

输出的9223372036854775807是常量NSNotFound的值。
当程序直接输出NSArray集合时,程序虽然会输出集合元素,但对于中文字符,则转换为\U75af格式的Unicode表示形式。

NSIndexSet集合:

NSIndexSet集合:与NSSet集合的功能基本相似,区别只是NSIndexSet集合主要用于保存索引值,因此,它的集合元素都是NSUInterger对象。

向NSArray集合后面追加元素:
  • 使用arrayByAddingObject:方法追加单个元素。
  • 使用arrayWithObjects:方法将另一个数组中所有的元素追加到原数组的后面。
NSSArray怎么判断集合是否包含指定元素:

只有某个集合元素与被查找元素通过isEqual:方法比较返回YES,即可认为该NSArray集合包含该元素,并不需要两个元素是同一个元素(即相同的地址)。

重写isEqual:
@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
@synthesize name;
@synthesize pass;
- (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);
}
//重写isEqual:方法,重写该方法的比较标准是,
//如果两个FKUser的name、pass相等,即可认为它们相等
- (BOOL) isEqual: (id) other {
    if (self == other) {
        return  YES;
    }
    //如果两个的类是相同的话就进入
    if ([other class] == FKUser.class) {
        FKUser* target = (FKUser*)other;
        return [self.name isEqualToString:target.name]
        && [self.pass isEqualToString:target.pass];
    }
    return  NO;
}
//重写description方法,可以直接看到FKUser对象的状态
- (NSString*) description {
    return [NSString stringWithFormat:
            @"<FKUser[name = %@, pass = %@]>"
            , self.name, self.pass];
}
@end

int main(int grac, char *grav[]) {
    @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对象在集合中的索引
        FKUser* newUser = [[FKUser alloc] initWithName:@"zhu" pass:@"654"];
        NSUInteger pos = [array indexOfObject:newUser];
        NSLog(@"newUser的位置为:%ld", pos);
    }
    return 0;
}

输出结果为:
23

该代码用于查找你定义的newUser对象在原NSArray数组中的索引位置,并将其输出。


7.5.2 对集合元素整体调用方法

简单地调用集合元素的方法,可通过NSArray的如下两种方法:
  • makeObjectsPerformSelector::依次调用NSArray集合中每个元素的指定方法,该方法需要传入一个SEL参数,用于指定调用那种方法,
  • makeObejectsPerformSelector:withObject::依次调用NSArray集合中每个元素的指定方法,该方法第一个SEL参数用于指定调用哪个方法;第二个参数用于调用集合元素的方法时传入参数;第三个参数用于控制是否终止迭代,如果在处理某个元素后,将第三个元素赋为YES,该方法就会中止迭代调用。
如果希望对某个集合中的所有元素进行隐式遍历,并使用集合元素来执行某一段代码,则可通过NSArray的如下方法来完成:
  • enumerateObjectsUsingBlock::遍历集合中的所有元素,并依次使用元素来执行指定的代码块。
  • enumerateObjectsWithOptions:usingBlock::遍历集合中的所有元素,并依次使用元素来执行指定的代码块。该方法可以额外传入一个参数,用于控制遍历的选项,如反向遍历。
  • enumerateObjectsAtIndexes:options:usingBlock::遍历集合中指定范围内的元素,并依次使用元素来执行指定的代码块。该方法可传入一个选项参数,用于控制遍历的选项,如反向遍历。

上面3个方法都需要传入一个代码块参数,该代码块(Block后)必须带3个参数,前一个参数代表正在遍历的集合元素,第二个参数代表正在遍历的集合元素的索引。

@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
@synthesize name;
@synthesize pass;
- (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);
}
//重写isEqual:方法,重写该方法的比较标准是,
//如果两个FKUser的name、pass相等,即可认为它们相等
- (BOOL) isEqual: (id) other {
    if (self == other) {
        return  YES;
    }
    //如果两个的类是相同的话就进入
    if ([other class] == FKUser.class) {
        FKUser* target = (FKUser*)other;
        return [self.name isEqualToString:target.name]
        && [self.pass isEqualToString:target.pass];
    }
    return  NO;
}
//重写description方法,可以直接看到FKUser对象的状态
- (NSString*) description {
    return [NSString stringWithFormat:
            @"<FKUser[name = %@, pass = %@]>"
            , self.name, self.pass];
}
@end

int main(int grac, char *grav[]) {
    @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:@"下午好,真好!"];
        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;
}

NSEnumerationReverse:将指定的长度的数组反转输出
输出结果为:
45

从执行结果可以看出,NSArray既可以对集合中所有的元素整体调用某个方法,也可通过NSIndexSet来控制只对集合中部分元素迭代调用指定的代码块。从运行就过可以看出,虽然程序只是调用NSArray的方法,但程序在执行这些方法时,底层实际上会使用循环进行迭代处理调用每个集合元素,因此,这些方法都可称为迭代方法


7.5.3 对NSArray进行排序

NSArray的排序方法都以sort开头,最常用的排序方法如下:
  • sortedArrayUsingFunction:context::该方法使用排序函数对集合元素进行排序,该排序函数必须返回NSOrderedDescending、NSOrderedAscending、NSOrderedSame这些枚举值,用于代表集合元素的大小。该方法返回一个排好序的新的NSArray对象。
  • sortedArrayUsingSelector::该方法使用集合元素自身的方法对集合元素进行排序,集合元素的该方法必须返回NSOrderedDescending、NSOrderedAscending、NSOrderedSame这些枚举值,用于代表集合元素的大小。该方法返回一个排好序的新的NSArray对象。
  • sortedArrayUsingComparator::该方法使用代码块对集合元素进行排序,该代码块必须返回NSOrderedDescending、NSOrderedAscending、NSOrderedSame这些枚举值,用于代表集合元素的大小。该方法返回一个排好序的新的NSArray对象。

实际上,sortedArrayUsingComparator:方法sortedArrayUsingFuntion:context:方法的简化版本。

排序实例:
//定义比较函数,根据两个对象的intvalue进行比较
NSInteger intSort(id num1, id num2, void* context) {
    int v1 = [num1 intValue];
    int v2 = [num2 intValue];
    if (v1 < v2) {
        return NSOrderedAscending;
    } else if (v1 > v2) {
        return NSOrderedDescending;
    } else {
        return NSOrderedSame;
    }
}

int main(int grac, char *grav[]) {
    @autoreleasepool {
        //初始化一个元素为NSString的NSArray对象
        NSArray* array1 = [NSArray arrayWithObjects:
                           @"Objective-C", @"C",
                           @"C++", @"Ruby", @"Perl", @"Python", nil];
        //使用集合元素的compare:方法进行排序
        array1 = [array1 sortedArrayUsingSelector:
                  @selector(compare:)];
        NSLog(@"%@", array1);
        //初始化一个元素为NSNumber的NSArray对象
        NSArray* array2 = [NSArray arrayWithObjects:
                           [NSNumber numberWithInt:20],
                           [NSNumber numberWithInt:12],
                           [NSNumber numberWithInt:-8],
                           [NSNumber numberWithInt:50],
                           [NSNumber numberWithInt:19], nil];
        //使用insSort函数进行排序
        array2 = [array2 sortedArrayUsingFunction:intSort
                                          context:nil];
        NSLog(@"%@", array2);
        //使用代码块对集合元素进行排序
        NSArray* array3 = [array2 sortedArrayUsingComparator:
                           ^(id obj1, id obj2)
                           {
            //该代码块就是根据集合元素的intValue进行比较
            if ([obj1 intValue] > [obj2 intValue]) {
                return NSOrderedDescending;
            } else if ([obj1 intValue] < [obj2 intValue]) {
                return NSOrderedAscending;
            } else {
                return NSOrderedSame;
            }
        }];
        NSLog(@"%@", array3);
    }
    return 0;
}

上面对NSArray进行了三种排序:
第一种是使用NSString自身的compare:方法进行排序。这是因为NSSting自身已经实现了compare:方法,这意味着NSString对象本身就可以比较大小——NSString比较大小的方法是根据字符对象的编码来进行的。
后面两种方式通过调用函数或者代码块来进行比较大小,代码块相当于一个匿名函数,因此后面两种方式的本质是一样的,它们都可以通过自定义的比较规则来比较集合元素的大小——不管集合元素本身是否可比较大小,只要程序通过比较函数或代码块定义自己的比较规则即可。

输出结果为:
32

自然排序:

集合元素本身可比较,而且直接利用集合元素比较大小方法进行排序的方式也被称为自然排序

定制排序:

通过比较函数或者代码块来指定自定义比较规则的方式,则被称为定制排序


7.5.4 使用枚举器遍历NSArray集合元素

对于NSArray对象,除了可根据集合元素的索引来遍历集合元素之外,还可以调用NSArray对象的如下两个方法来返回枚举器:
  • objectEnumerator:返回NSArray集合的顺序枚举器。
  • reverseObjectEnumerator:返回NSArray集合的逆序枚举器。
NSEnumerator枚举器包含的两个方法:
  • allObjects:获取被枚举集合中的所有元素。
  • nextObject:获取被枚举集合中的下一个元素。

一般来说,借助nextObject方法即可对集合元素进行枚举:程序可采用循环不断获取nextObject方法的返回值,直到该方法的返回值为nil结束循环。

使用NSEnumerator遍历集合元素的示例程序:
int main(int grac, char *grav[]) {
    @autoreleasepool {
    //之前使用数组时,将“孙悟空”“宝玉”“黛玉”存入了“myFile.txt”,现在读取该文件
        NSArray* array = [NSArray arrayWithContentsOfFile:
                          @"myFile.txt"];
        NSEnumerator* en = [array objectEnumerator];
        id object;
        while (object = [en nextObject]) {
            NSLog(@"%@", object);
        }
        NSLog(@"-------下面逆序遍历-------");
        en = [array reverseObjectEnumerator];
        while (object = [en nextObject]) {
            NSLog(@"%@", object);
        }
    }
    return 0;
}

输出结果为:
34


7.5.5 快速枚举(for…in)

快速枚举的方法可以遍历NSArray、NSSet、NSDictionary等集合,使用快速枚举,无须获得集合的长度,也无须根据索引来访问集合元素,即可快速枚举自动遍历集合的每个元素。

快速枚举的语法格式如下:
for (type variableName in collection) {
   //variableName自动迭代访问每个元素...
}

type是集合元素的类型
variableName是一个形参名
collection代表你要遍历的元素集合
快速枚举将自动将集合元素依次赋给该变量

注:

如果使用快速枚举来遍历NSDictionary对象,快速枚举中循环计数器依次代表NSDictionary的每个key的值。

快速枚举的示范:
int main(int argc, char* argv[]) {
    @autoreleasepool {
    //之前使用数组时,将“孙悟空”“宝玉”“黛玉”存入了“myFile.txt”,现在读取该文件
        NSArray* array = [NSArray arrayWithContentsOfFile:
                          @"myFile.txt"];
        for (id object in array) {
            NSLog(@"%@", object);
        }
    }
    return 0;
}

输出结果为:
345

  • 快速枚举遍历数组元素无须获得数组长度,也无须根据索引来访问数组元素。
快速枚举的本质:
  • 快速枚举的本质是一个foreach循环,foreach循环和普通循环不同的是,它无须循环条件,也无须循环迭代语句,这些部分都由系统来完成,foreach循环自动迭代数组的每个元素,当每个元素都被迭代一次后,foreach循环自动结束。

7.5.6 可变数组(NSMutableArray)

NSArray代表集合元素不可变的集合,一旦NSArray创建成功,程序不能向集合中添加新的元素,不能删除集合中已有的元素,也不能替换集合元素。

NSArray只是保存对象的指针,因此,NSArray只保证这些指针变量中的地址不能改变,但指针变量所指向的对象是可以改变的。

NSMutableArray是NSArray 的子类,所以在原基础上有了许多扩展。

NSMutableArray代表集合元素可变的集合,而NSMutableArray底层采用传统的数组来容纳集合元素,因此,创建NSMutableArray时可通过参数指定底层数组的厨师容量。

NSMutableArray新增的方法:
  • 添加集合元素的方法:这类方法以add开头
  • 删除集合元素的方法:这类方法以remove开头
  • 替换集合元素的方法:这列方法以replace开头
  • 对集合本身排序的方法:这类方法以sort开头

NSMutableArray同样提供了sortUsingSelector、sortUsingComparator、sortUsingFunction:context:这三个方法,这三个方法与前面介绍的NSArray提供的三个排序方法用法基本相似,区别是NSArray的排序方法时返回一个新的、排好序的NSArray对象,而NSMutableArray的排序方法则是对集合本身排序。

改变NSMutableArray集合中的元素:
//定义一个函数,该函数用于把NSArray集合转换为字符串
NSString* NSCollectionToString(NSArray* array) {
    NSMutableString* result = [NSMutableString
                               stringWithString:@"["];
    for (id object in array) {
        [result appendString:[object description]];
        [result appendString:@","];
    }
    NSUInteger len = [result length];   //获取字符串长度
    //去掉字符串最后的一个字符
    [result deleteCharactersInRange:NSMakeRange(len - 1, 1)];
    [result appendString:@"]"];
    return result;
}

int main(int argc, char* argv[]) {
    @autoreleasepool {
        //之前使用数组时,将“孙悟空”“宝玉”“黛玉”存入了“myFile.txt”,现在读取该文件来初始化NSMutableArray集合
        NSMutableArray* array = [NSMutableArray
                                 arrayWithContentsOfFile:@"myFile.txt"];
        [array addObject:@"疯狂iOS讲义"]; //向集合最后添加一个元素
        NSLog(@"最后追加一个元素后:%@", NSCollectionToString(array));
        //使用NSArray向集合尾部添加多个元素
        [array addObjectsFromArray:[NSArray
                                    arrayWithObjects:@"张飞", @"关羽", nil]];
        NSLog(@"最后追加两个元素后:%@", NSCollectionToString(array));
        //向集合的指定位置插入一个元素
        [array insertObject:@"疯狂Ajax讲义" atIndex:2];
        NSLog(@"在索引为2处插入一个元素后:%@",NSCollectionToString(array));
        //使用NSArray向集合指定位置插入多个元素
        [array insertObjects:[NSArray arrayWithObjects:@"武松", @"林冲", nil]
                   atIndexes:[NSIndexSet indexSetWithIndexesInRange:
                              NSMakeRange(3, 2)]];
        NSLog(@"插入多个元素后:%@", NSCollectionToString(array));
        //删除集合最后一个元素
        [array removeLastObject];
        NSLog(@"删除最后一个元素后:%@", NSCollectionToString(array));
        //删除集合中指定索引处的元素
        [array removeObjectAtIndex:5];
        NSLog(@"删除索引为5处的元素后:%@", NSCollectionToString(array));
        //删除索引为2开始的3个元素
        [array removeObjectsInRange:NSMakeRange(2, 3)];
        NSLog(@"删除索引为2~5处的元素后:%@", NSCollectionToString(array));
        //替换索引为2处的元素
        [array replaceObjectAtIndex:2 withObject:@"疯狂Android讲义"];
        NSLog(@"替换索引为2处的元素后:%@", NSCollectionToString(array));
    }
    return 0;
}

输出结果为:
5645

NSMutableArray与NSArray相比,最大的区别就是添加用于“添加元素”、“删除元素”、“替换元素”的三种方法。


7.5.7 NSArray的KVC与KVO

NSArray是一个容纳多个对象的集合,NSArray允许直接对集合中的所有元素进行整体的KVC编码,NSArray提供了如下两个方法:
  • setValue:forKey::将NSArray集合中所有元素的指定key对应属性或实例变量设置为value。
  • valueForKey::返回该NSArray集合中所有元素指定key组成的NSArray方法。
NSArray还为集合中的所有元素或部分元素进行KVO编程提供如下方法:
  • addObserver:forKeyPath:options:context::为集合中的所有元素添加KVO监听器。
  • removeObserver:forKeyPath::为集合中的所有元素删除KVO监听器。
  • addObserver:toObjectsAtIndexes:forKeyPath:options:context::为集合中指定索引处的元素添加KVO监听器。
  • removeObserver:fromObjectsAtIndexes:forKeyPath::为集合中指定索引处的元素删除KVO监听器。
对NSArray集合中的所有元素整体进行KVC编程:
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@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

NS_ASSUME_NONNULL_END

#import "FKUser.h"

@implementation FKUser
@synthesize name;
@synthesize pass;
- (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);
}
//重写isEqual:方法,重写该方法的比较标准是,
//如果两个FKUser的name、pass相等,即可认为它们相等
- (BOOL) isEqual: (id) other {
    if (self == other) {
        return  YES;
    }
    //如果两个的类是相同的话就进入
    if ([other class] == FKUser.class) {
        FKUser* target = (FKUser*)other;
        return [self.name isEqualToString:target.name]
        && [self.pass isEqualToString:target.pass];
    }
    return  NO;
}
//重写description方法,可以直接看到FKUser对象的状态
- (NSString*) description {
    return [NSString stringWithFormat:
            @"<FKUser[name = %@, pass = %@]>"
            , self.name, self.pass];
}
@end


#import <Foundation/Foundation.h>
#import "FKUser.h"
//定义一个函数,该函数用于把NSArray集合转换为字符串
NSString* NSCollectionToString(NSArray* array) {
    NSMutableString* result = [NSMutableString
                               stringWithString:@"["];
    for (id object in array) {
        [result appendString:[object description]];
        [result appendString:@","];
    }
    NSUInteger len = [result length];   //获取字符串长度
    //去掉字符串最后的一个字符
    [result deleteCharactersInRange:NSMakeRange(len - 1, 1)];
    [result appendString:@"]"];
    return result;
}

int main(int argc, char* argv[]) {
    @autoreleasepool {
        //初始化NSArray对象
        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];
        //获取所有集合元素的name属性组成的新集合
        id newArr = [array valueForKey:@"name"];
        NSLog(@"%@", NSCollectionToString(newArr));
        //对集合中的所有元素整体进行KVC编程
        //对所有集合元素的name属性改为“新名字”
        [array setValue:@"新名字" forKey:@"name"];
        NSLog(@"%@", NSCollectionToString(array));
    }
    return 0;
}

输出结果为:
35

从运行结果看,newArr = [array valueForKey:@“name”];代码一次性将NSArray集合中所有元素的name属性取出来了;[array setValue:@“新名字” forKey:@“name”];代码则全部将NSArray集合中所有元素的name属性值都改成新值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值