Apple开发_NSArray、NSMutableArray

前言

  • 数组只能存储 OC 对象,不能存储 C 语言中的基本数据类型,也不能存储 nil 。
  • Xcode 7 对系统中常用的一系列容器类型都增加了泛型支持(),有了泛型后就可以指定容器类中对象的类型了。
  • 假如向泛型容器中加入错误的对象,编译器会报警告。
    • __covariant:协变性,子类型可以强转到父类型(里氏替换原则)。
    • __contravariant:逆变性,父类型可以强转到子类型。
  • 不指定泛型类型的对象可以和任意泛型类型转化,但指定了泛型类型后,两个不同类型间是不可以强转的,
  • 假如你希望主动控制转化关系,就需要使用泛型的协变性和逆变性修饰符。

1、不可变数组 NSArray 的创建

// 直接创建不可变数组
/*
数组成员是 id 类型,表示数组元素可以是任意的 oc 对象。
*/
NSArray *arr1 = @[@"bei", @"jing", @"huan", @"ying", @"nin"];

// 对象方法创建
NSArray *arr2 = [[NSArray alloc] init];

// 和 arr1 的地址不相同
NSArray *arr3 = [[NSArray alloc] initWithArray:arr1];

NSArray *arr4 = [[NSArray alloc] initWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];

// 类方法创建
NSArray *arr5 = [NSArray array];

// 和 arr1 的地址不相同
NSArray *arr6 = [NSArray arrayWithArray:arr1];

// 创建只有一个元素(id)的数组
NSArray *arr7 = [NSArray arrayWithObject:@"qian"];

NSArray *arr8 = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];

// 从 文件 创建字符串
NSString *path = [NSHomeDirectory() stringByAppendingString:@"/Desktop/test.txt"];

NSArray *arr9 = [[NSArray alloc] initWithContentsOfFile:path];
NSArray *arr10 = [NSArray arrayWithContentsOfFile:path];

// 从 Url 创建字符串
/*
file:// 文件前缀
*/
NSURL *url = [NSURL URLWithString:[@"file://" stringByAppendingString:[NSHomeDirectory() stringByAppendingString:@"/Desktop/test.txt"]]];

NSArray *arr11 = [[NSArray alloc] initWithContentsOfURL:url];
NSArray *arr12 = [NSArray arrayWithContentsOfURL:url];

// 泛型定义

// 指明数组中存放的是 NSString 类型数据
NSArray<NSString *> *arr13 = @[@"bei", @"jing", @"huan", @"ying", @"nin"];

// 指明数组中存放的是 NSNumber 类型数据
NSArray<NSNumber *> *arr14 = @[@2, @4, @6, @8, @10];

2、成员个数计算

NSArray *arr = @[@"bei", @"jing", @"huan", @"ying", @"nin"];

NSUInteger length = [arr count];

3、取成员

NSArray *arr = @[@"bei", @"jing", @"huan", @"ying", @"nin"];

// []
NSArray *arr1 = arr[1];

// objectAtIndex
NSArray *arr2 = [arr objectAtIndex:2];

// subarrayWithRange
NSArray *arr3 = [arr subarrayWithRange:NSMakeRange(2, 2)];

// for...in 循环
/*
取出数组中的每个元素,分别保存在 tmp 中
*/
for (NSString *tmp in arr) {

    NSLog(@"%@", tmp);
}

// id (void *) 泛型指针, 取出数组中的每个元素,分别保存在 tmp 中
for (id tmp in arr) {

    NSLog(@"tmp = %@", tmp);
}

4、取最后一个元素

NSArray *arr = @[@"bei", @"jing", @"huan", @"ying", @"nin"];

id lastObject1 = [arr lastObject];

id lastObject2 = arr[[arr count]-1];

5、由元素的值获取下标

NSArray *arr = @[@"bei", @"jing", @"huan", @"ying", @"nin"];

NSUInteger index = [arr indexOfObject:@"huan"];

6、判断数组中是否包含某个元素

NSArray *arr = @[@"bei", @"jing", @"huan", @"ying", @"nin"];

BOOL result = [arr containsObject:@"huan"];

7、数组的比较

NSArray *arr1 = @[@"bei", @"jing", @"huan", @"ying", @"nin"];
NSArray *arr2 = @[@"ni", @"hao", @"bei", @"jing"];

// isEqualToArray

// 比较两个数组内容是否相同
BOOL bl = [arr1 isEqualToArray:arr2];

// firstObjectCommonWithArray

// 返回两个数组中第一个相同的元素
NSString *str = [arr1 firstObjectCommonWithArray:arr2];

8、组合

NSArray *arr1 = @[@"bei", @"jing", @"huan", @"ying", @"nin"];
NSArray *arr2 = @[@"Users", @"JHQ0228", @"Desktop"];

// 按指定字符组合
NSString *str1 = [arr1 componentsJoinedByString:@" "];

// 按路径组合
/*
将数组中的元素自动组合成路径,在每个元素之间自动加上 “/”
*/
NSString *str2 = [NSString pathWithComponents:arr2];

9、可变数组 NSMutableArray 的创建

// 对象方法创建
/*
创建指定长度的数组,预先分配空间,提高效率,实际长度可大于指定长度
*/
NSMutableArray *arr1 = [[NSMutableArray alloc] initWithCapacity:0];

// 类方法创建
/*
创建指定长度的数组,预先分配空间,提高效率,实际长度可大于指定长度
*/
NSMutableArray *arr2 = [NSMutableArray arrayWithCapacity:0];

10、元素的添加

NSMutableArray *arr = [NSMutableArray arrayWithCapacity:0];

// addObject

// 向数组中追加一个元素
[arr addObject:@"bei"];

// addObjectsFromArray

// 追加数组
NSArray *arrAdd = @[@"dian", @"ying", @"xue", @"yuan"];
[arr addObjectsFromArray:arrAdd];

// insertObject... atIndex

// 在数组中任意位置插入一个元素
[arr insertObject:@"hao" atIndex:2];

// arrayByAddingObject

// 向数组添加一个元素,返回一个新的数组
NSArray *arr1 = [arr arrayByAddingObject:@"ma"];

11、元素的删除

NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"nan", @"jing", @"huan", @"ying", @"nin", @"bei", @"jing", @"ni", @"hao", nil];

// 删除指定下标的元素
[arr removeObjectAtIndex:2];

// 删除指定元素,删除所有指定元素
[arr removeObject:@"ying"];

// 删除指定元素
[arr removeObjectIdenticalTo:@"nan"];

// 删除指定范围的元素
NSRange range = {2,1};
[arr removeObjectsInRange:range];

// 删除最后一个元素
[arr removeLastObject];

// 删除所有元素
[arr removeAllObjects];

12、元素的替换

NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"nan", @"jing", @"hao", nil];

// 替换指定下标元素
[arr replaceObjectAtIndex:1 withObject:@"ren"];

13、元素的交换

NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"bei", @"jing", @"nin", @"hao", nil];

[arr exchangeObjectAtIndex:0 withObjectAtIndex:1];

14、元素的修改

NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"bei", @"jing", @"nin", @"hao", nil];

// 修改整个数组(覆盖重写)
[arr setArray:@[@"bei", @"jing", @"huan", @"ying",  @"nin"]];

// 修改数组中的某个元素
arr[3] = @"huan";

15、给数组里的所有元素发送一个消息

Student *stu1 = [[Student alloc] init];
Student *stu2 = [[Student alloc] init];
Student *stu3 = [[Student alloc] init];

NSArray *arr = [NSArray arrayWithObjects:stu1, stu2, stu3, nil];

// 发送消息
[arr makeObjectsPerformSelector:@selector(studentTest)];

16、遍历

  • 16.1 用 for 循环遍历

NSArray * array = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];

for (int i = 0; i < [array count]; i ++) {

NSLog(@"%@", array[i]);
}
  • 16.2 用 for...in 循环遍历

NSArray *array = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];

// id (void *) 泛型指针, 取出数组中的每个元素,分别保存在 tmp 中
for (id tmp in array) {

    NSLog(@"%@", tmp);
}

// 取出数组中的每个元素,分别保存在 tmp 中
for (NSString *tmp in array) {

    NSLog(@"%@", tmp);
}
  • 16.3 用 block 循环遍历

NSArray *array = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];

[array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

    // obj == array[i],idx == i
    NSLog(@"%@", obj);

    if ([obj  isEqual: @"huan"]) {

        // 停止遍历
        *stop = YES;
    }
}];
  • 16.4 用迭代器遍历

NSArray *array = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];

// 获取数组的正序迭代器
NSEnumerator *enu1 = [array objectEnumerator];

// 获取数组的反序迭代器
NSEnumerator *enu2 = [array reverseObjectEnumerator];

id obj = nil;

// 正序,获取下一个需要遍历的元素
while (obj = [enu1 nextObject]) {

    NSLog(@"%@", obj);
}

// 反序,获取下一个需要遍历的元素
while (obj = [enu2 nextObject]) {

    NSLog(@"%@", obj);
}
  • 16.5 条件遍历

// 1.indexesOfObjectsPassingTest

NSArray *array = [NSArray arrayWithObjects:@3, @8, @17, @2, @25, @6, @89, nil];

NSIndexSet *indexSet = [array indexesOfObjectsPassingTest:^BOOL(id  _Nonnull obj, 
    NSUInteger idx, 
    BOOL * _Nonnull stop) {
        // 遍历数组,找出数组中所有大于 10 的元素的位置
        return [obj intValue] > 10 ? : NO;
    }];


[indexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
    // 输出所有大于 10 的元素值
    NSLog(@"%@", array[idx]);
}];

// 2.indexOfObjectPassingTest

NSUInteger index = [array indexOfObjectPassingTest:^BOOL(id  _Nonnull obj, 
    NSUInteger idx, 
    BOOL * _Nonnull stop) {

        // 遍历数组,找出数组中第一个大于 10 的元素的位置
        return [obj intValue] > 10 ? : NO;
}];

// 输出第一个大于 10 的元素值
NSLog(@"%@", array[index]);

17、排序

  • 17.1 冒泡排序

NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"sunday", @"sunny", @"summer", @"sun", nil];

for (int i = 0; i < [arr count] - 1; i++) {
    for (int j = 0; j < [arr count] - 1 - i; j++) {

        // 大小判断 arr[j] > arr[j + 1]
        if ([arr[j] compare:arr[j + 1]] == NSOrderedDescending) {

            // 位置交换
            [arr exchangeObjectAtIndex:j withObjectAtIndex:(j + 1)];
        }
    }
}
  • 17.2 用指定的方法排序

// 1.用指定的方法排序,可变数组排序

NSMutableArray *arr1 = [NSMutableArray arrayWithObjects:@"sunday", @"sunny", @"summer", @"sun", nil];

// 原数组的顺序改变,指定元素的比较方法:compare:,默认排序方式为升序排列
[arr1 sortUsingSelector:@selector(compare:)];

// 使排序结果 降序 排列
NSEnumerator *enu = [arr1 reverseObjectEnumerator];

id obj = nil;
while (obj = [enu nextObject]) {

    // 排序后的结果为降序
    NSLog(@"%@", obj);
}

// 2.用指定的方法排序,不可变数组排序

NSArray *arr2 = [NSArray arrayWithObjects:@"sunday", @"sunny", @"summer", @"sun", nil];

// 返回一个排好的数组,原数组的顺序不变,指定元素的比较方法:compare:
NSArray *arr3 = [arr2 sortedArrayUsingSelector:@selector(compare:)];

// 3.用指定的方法排序,自定义类

//  People.h

#import <Foundation/Foundation.h>

@interface People : NSObject

// 名
@property (nonatomic, retain) NSString *firstname;

// 姓
@property (nonatomic, retain) NSString *lastname;

+ (id)peopleWithFirstname:(NSString *)firstname lastname:(NSString *)lastname;

// 返回值类型为 NSComparisonResult
- (NSComparisonResult)comparePeople:(People *)peop;

@end

//  People.m

#import "People.h"

@implementation People

+ (id)peopleWithFirstname:(NSString *)firstname lastname:(NSString *)lastname {
    People * peop = [[People alloc] init];

    peop.lastname = lastname;
    peop.firstname = firstname;

    return peop;
}

- (NSComparisonResult)comparePeople:(People *)peop {

    // 先按照姓排序
    NSComparisonResult result = [self.lastname compare: peop.lastname];

    if (result == NSOrderedSame) {

        // 如果有相同的姓,就比较名字
        result = [self.firstname compare: peop.firstname];
    }

    return result;
}

- (NSString *)description{

    return [NSString stringWithFormat:@"%@ %@", self.firstname, self.lastname];
}

@end

//  main.m

#import "People.h"

People *peop1 = [People peopleWithFirstname:@"MingJie" lastname:@"Li"];
People *peop2 = [People peopleWithFirstname:@"LongHu" lastname:@"Huang"];
People *peop3 = [People peopleWithFirstname:@"LianJie" lastname:@"Li"];
People *peop4 = [People peopleWithFirstname:@"Jian" lastname:@"Xiao"];

// 1.用指定的方法排序,可变数组排序

NSMutableArray *array1 = [NSMutableArray arrayWithObjects:peop1, peop2, peop3, peop4, nil];

// 原数组的顺序改变
[array1 sortUsingSelector:@selector(comparePeople:)];

// 2.用指定的方法排序,不可变数组排序

NSArray *array2 = [NSArray arrayWithObjects:peop1, peop2, peop3, peop4, nil];

// 返回一个排好的数组,原数组的顺序不变
NSArray *array3 = [array2 sortedArrayUsingSelector:@selector(comparePeople:)];
  • 17.3 用 Block 排序

// 1.利用 block 进行排序,可变数组排序

NSMutableArray *arr1 = [NSMutableArray arrayWithObjects:@"sunday", @"sunny", @"summer", @"sun", nil];

[arr1 sortUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {

    // 指定比较的方法,两个元素值比较
    NSComparisonResult result = [obj1 compare:obj2];

    // 返回比较的结果
    return result;
}];

// 2.利用 block 进行排序,不可变数组排序

NSArray *arr2 = [NSArray arrayWithObjects:@"sunday", @"sunny", @"summer", @"sun", nil];

// 返回一个排好的数组
NSArray *arr3 = [arr2 sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {

    // 指定比较的方法,两个元素值比较
    NSComparisonResult result = [obj1 compare:obj2];

    // 返回比较的结果
    return result;
}];

// 3.利用 block 进行排序,自定义类

// People1.h

#import <Foundation/Foundation.h>

@interface People1 : NSObject

// 名
@property (nonatomic, retain) NSString *firstname;

// 姓
@property (nonatomic, retain) NSString *lastname;

+ (id)peopleWithFirstname:(NSString *)firstname lastname:(NSString *)lastname;

@end

// People1.m

#import "People1.h”

@implementation People1

+ (id)peopleWithFirstname:(NSString *)firstname lastname:(NSString *)lastname {
    People1 * peop = [[People1 alloc] init];

    peop.lastname = lastname;
    peop.firstname = firstname;

    return peop;
}

- (NSString *)description{

    return [NSString stringWithFormat:@"%@ %@", self.firstname, self.lastname];
}

@end

// main.m

#import "People1.h”

People1 *peop1 = [People1 peopleWithFirstname:@"MingJie" lastname:@"Li"];
People1 *peop2 = [People1 peopleWithFirstname:@"LongHu" lastname:@"Huang"];
People1 *peop3 = [People1 peopleWithFirstname:@"LianJie" lastname:@"Li"];
People1 *peop4 = [People1 peopleWithFirstname:@"Jian" lastname:@"Xiao"];

// 1.利用 block 进行排序,可变数组排序

NSMutableArray *array1 = [NSMutableArray arrayWithObjects:peop1, peop2, peop3, peop4, nil];

[array1 sortUsingComparator:^NSComparisonResult(People1 *  _Nonnull obj1, People1 *  _Nonnull obj2) {

    // 先按照姓排序
    NSComparisonResult result = [obj1.lastname compare:obj2.lastname];

    if (result == NSOrderedSame) {

        // 如果有相同的姓,就比较名字
        result = [obj1.firstname compare:obj2.firstname];
    }

    return result;
}];

// 2.利用 block 进行排序,不可变数组排序

NSArray *array2 = [NSArray arrayWithObjects:peop1, peop2, peop3, peop4, nil];

NSArray *array3 = [array2 sortedArrayUsingComparator:^NSComparisonResult(People1 *  _Nonnull obj1, 
People1 *  _Nonnull obj2) {

    // 先按照姓排序
    NSComparisonResult result = [obj1.lastname compare:obj2.lastname];

    if (result == NSOrderedSame) {

        // 如果有相同的姓,就比较名字
        result = [obj1.firstname compare:obj2.firstname];
    }

return result;
}];
  • 17.4 按描述器排序

//  Book.h

#import <Foundation/Foundation.h>

@interface Book : NSObject

@property (nonatomic, retain) NSString *name;

+ (id)bookWithName:(NSString *)name;

@end

//  Book.m

#import "Book.h"

@implementation Book

+ (id)bookWithName:(NSString *)name {
    Book *book = [[Book alloc] init];
    book.name = name;
    return book;
}

@end

//  People2.h

#import <Foundation/Foundation.h>

@class Book;

@interface People2 : NSObject

// 名
@property (nonatomic, retain) NSString *firstname;

// 姓
@property (nonatomic, retain) NSString *lastname;

// 书
@property (nonatomic, retain) Book *book;

+ (id)peopleWithFirstname:(NSString *)firstname lastname:(NSString *)lastname bookName:(NSString *)bookName;

@end

//  People2.m

#import "People2.h"
#import "Book.h"

@implementation People2

+ (id)peopleWithFirstname:(NSString *)firstname lastname:(NSString *)lastname bookName:(NSString *)bookName {

    People2 *peop = [[People2 alloc] init];

    peop.lastname = lastname;
    peop.firstname = firstname;
    peop.book = [Book bookWithName:bookName];

    return peop;
}

- (NSString *)description{

    return [NSString stringWithFormat:@"%@ %@, bookName: %@", self.firstname, self.lastname, self.book.name];
}

@end

// main.m

#import "People2.h"

People2 *peop1 = [People2 peopleWithFirstname:@"MingJie" lastname:@"Li" bookName:@"book1"];
People2 *peop2 = [People2 peopleWithFirstname:@"LongHu" lastname:@"Huang" bookName:@"book2"];
People2 *peop3 = [People2 peopleWithFirstname:@"LianJie" lastname:@"Li" bookName:@"book2"];
People2 *peop4 = [People2 peopleWithFirstname:@"Jian" lastname:@"Xiao" bookName:@"book1"];

// 先按照书名进行排序
/*
这里的 key 写的是 @property 的名称
*/
NSSortDescriptor *bookNameDesc = [NSSortDescriptor sortDescriptorWithKey:@"book.name" ascending:YES];

// 再按照姓进行排序
NSSortDescriptor *lastnameDesc = [NSSortDescriptor sortDescriptorWithKey:@"lastname" ascending:YES];

// 再按照名进行排序
NSSortDescriptor *firstnameDesc = [NSSortDescriptor sortDescriptorWithKey:@"firstname" ascending:YES];

// 1.按描述器排序,可变数组排序

NSMutableArray *array1 = [NSMutableArray arrayWithObjects:peop1, peop2, peop3, peop4, nil];

// 按顺序添加排序描述器
NSMutableArray *descs1 = [NSMutableArray arrayWithObjects:bookNameDesc, lastnameDesc, firstnameDesc, nil];

[array1 sortUsingDescriptors:descs1];

// 2.按描述器排序,不可变数组排序

NSArray *array2 = [NSArray arrayWithObjects:peop1, peop2, peop3, peop4, nil];

// 按顺序添加排序描述器
NSArray *descs2 = [NSArray arrayWithObjects:bookNameDesc, lastnameDesc, firstnameDesc, nil];

NSArray *array3 = [array2 sortedArrayUsingDescriptors:descs2];

0、前言

1、创建示例

2、API说明

@interface NSArray<__covariant ObjectType> : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>

/**
 * @brief 获取数组中指定下标的元素
 *
 * @param index     指定下标
 *
 * @return          返回指定下标的元素
 *
 * @discussion      如果数组中不存在指定下标的元素会导致程序崩溃
 */
- (ObjectType)objectAtIndex:(NSUInteger)index;

/**
 * @brief 初始化一个空数组对象
 *
 * @return          返回一个空数组对象
 *
 * @discussion      通常用于创建一个空的可变数组,然后逐步添加元素
 */
- (instancetype)init NS_DESIGNATED_INITIALIZER;

/**
 * @brief 根据给定的对象和数量初始化数组对象
 *
 * @param objects   给定的对象数组
 * @param cnt       数组中对象的数量
 *
 * @return          返回初始化后的数组对象
 *
 * @discussion      通常用于创建一个不可变数组,数组中的对象不能修改
 */
- (instancetype)initWithObjects:(const ObjectType _Nonnull [_Nullable])objects count:(NSUInteger)cnt NS_DESIGNATED_INITIALIZER;

/**
 * @brief 根据给定的解码器初始化数组对象
 *
 * @param coder     给定的解码器
 *
 * @return          返回初始化后的数组对象
 *
 * @discussion      通常用于解码器解码数据时,将数据转换成数组对象
 */
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

/** 数组中元素的个数 */
@property(readonly) NSUInteger count;

@end

@interface NSArray<ObjectType> (NSExtendedArray)

/**
 * @brief 将指定对象添加到数组中,并返回新的数组
 *
 * @param anObject        待添加的对象
 *
 * @return                返回新的数组,包含原数组中的所有对象和要添加的对象
 *
 * @usage                适用于需要在已有数组的基础上新增一个对象的场景
 */
- (NSArray<ObjectType> *)arrayByAddingObject:(ObjectType)anObject;

/**
 * @brief 将另一个数组中的所有对象添加到当前数组中,并返回新的数组
 *
 * @param otherArray      待添加的数组
 *
 * @return                返回新的数组,包含原数组中的所有对象和要添加的数组中的所有对象
 *
 * @usage                适用于需要将另一个数组中的所有对象添加到当前数组的场景
 */
- (NSArray<ObjectType> *)arrayByAddingObjectsFromArray:(NSArray<ObjectType> *)otherArray;

/**
 * @brief 将数组中的所有元素按照指定分隔符拼接成一个字符串
 *
 * @param separator       分隔符
 *
 * @return                返回拼接后的字符串
 *
 * @usage                适用于需要将数组中的元素拼接成一个字符串的场景,比如将一个数组中的所有元素用逗号分隔拼接成一个字符串
 */
- (NSString *)componentsJoinedByString:(NSString *)separator;

/**
 * @brief 判断数组中是否包含指定对象
 *
 * @param anObject        待判断的对象
 *
 * @return                如果数组中包含指定对象,则返回YES,否则返回NO
 *
 * @usage                适用于需要判断数组中是否包含某个对象的场景
 */
- (BOOL)containsObject:(ObjectType)anObject;

/**
 * @brief 返回数组的描述信息
 *
 * @param locale          本地化对象
 *
 * @return                返回数组的描述信息
 *
 * @usage                适用于需要获取数组的描述信息的场景
 */
- (NSString *)descriptionWithLocale:(nullable id)locale;

/**
 * @brief 返回数组的描述信息,并指定缩进级别
 *
 * @param locale          本地化对象
 * @param level           缩进级别
 *
 * @return                返回数组的描述信息
 *
 * @usage                适用于需要获取数组的描述信息,并指定缩进级别的场景
 */
- (NSString *)descriptionWithLocale:(nullable id)locale indent:(NSUInteger)level;

/**
 * @brief 返回当前数组和指定数组中第一个相同的对象
 *
 * @param otherArray      另一个数组
 *
 * @return                返回当前数组和指定数组中第一个相同的对象,如果没有相同的对象,则返回nil
 *
 * @usage                适用于需要查找两个数组中第一个相同对象的场景
 */
- (nullable ObjectType)firstObjectCommonWithArray:(NSArray<ObjectType> *)otherArray;

/**
 * @brief 获取数组中指定范围内的所有对象
 *
 * @param objects         用于返回获取到的对象的数组
 * @param range           指定范围
 *
 * @usage                适用于需要获取数组中指定范围内的所有对象的场景
 */
- (void)getObjects:(ObjectType _Nonnull __unsafe_unretained [_Nonnull])objects range:(NSRange)range NS_SWIFT_UNAVAILABLE("Use 'subarrayWithRange()' instead");

/**
 * @brief 返回指定对象在数组中第一次出现的位置
 *
 * @param anObject        待查找的对象
 *
 * @return                返回指定对象在数组中第一次出现的位置,如果没有找到,则返回NSNotFound
 *
 * @usage                适用于需要查找指定对象在数组中第一次出现的位置的场景
 */
- (NSUInteger)indexOfObject:(ObjectType)anObject;

/**
 * @brief 返回指定对象在数组指定范围内第一次出现的位置
 *
 * @param anObject        待查找的对象
 * @param range           指定范围
 *
 * @return                返回指定对象在数组指定范围内第一次出现的位置,如果没有找到,则返回NSNotFound
 *
 * @usage                适用于需要查找指定对象在数组指定范围内第一次出现的位置的场景
 */
- (NSUInteger)indexOfObject:(ObjectType)anObject inRange:(NSRange)range;

/**
 * @brief 返回指定对象在数组中第一次出现的位置(使用指针地址判断)
 *
 * @param anObject        待查找的对象
 *
 * @return                返回指定对象在数组中第一次出现的位置,如果没有找到,则返回NSNotFound
 *
 * @usage                适用于需要查找指定对象在数组中第一次出现的位置(使用指针地址判断)的场景
 */
- (NSUInteger)indexOfObjectIdenticalTo:(ObjectType)anObject;

/**
 * @brief 返回指定对象在数组指定范围内第一次出现的位置(使用指针地址判断)
 *
 * @param anObject        待查找的对象
 * @param range           指定范围
 *
 * @return                返回指定对象在数组指定范围内第一次出现的位置,如果没有找到,则返回NSNotFound
 *
 * @usage                适用于需要查找指定对象在数组指定范围内第一次出现的位置(使用指针地址判断)的场景
 */
- (NSUInteger)indexOfObjectIdenticalTo:(ObjectType)anObject inRange:(NSRange)range;

/**
 * @brief 判断当前数组和指定数组是否相等
 *
 * @param otherArray      待比较的数组
 *
 * @return                如果两个数组相等,则返回YES,否则返回NO
 *
 * @usage                适用于需要判断两个数组是否相等的场景
 */
- (BOOL)isEqualToArray:(NSArray<ObjectType> *)otherArray;

/**
 * @brief 返回数组的枚举器
 *
 * @return                返回数组的枚举器
 *
 * @usage                适用于需要遍历数组的场景
 */
- (NSEnumerator<ObjectType> *)objectEnumerator;

/**
 * @brief 返回数组反向遍历的枚举器
 *
 * @return                返回数组反向遍历的枚举器
 *
 * @usage                适用于需要反向遍历数组的场景
 */
- (NSEnumerator<ObjectType> *)reverseObjectEnumerator;

/**
 * @brief 使用指定的比较器函数对数组进行排序
 *
 * @param comparator    比较器函数,用于比较数组中元素的大小关系
 * @param context       上下文信息,可选参数
 *
 * @return 排序后的数组
 *
 * @note 使用场景:需要对数组进行排序,但是使用系统提供的排序方法无法满足需求时,可使用该方法自定义比较器函数进行排序。
 *       示例:假设有一个数组存储了多个人的信息,需要按照年龄从小到大排序,可以自定义比较器函数,然后调用该方法进行排序。
 */
- (NSArray<ObjectType> *)sortedArrayUsingFunction:(NSInteger (NS_NOESCAPE *)(ObjectType, ObjectType, void * _Nullable))comparator context:(nullable void *)context;

/**
 * @brief 使用指定的比较器函数和提示数据对数组进行排序
 *
 * @param comparator    比较器函数,用于比较数组中元素的大小关系
 * @param context       上下文信息,可选参数
 * @param hint          提示数据,可选参数
 *
 * @return 排序后的数组
 *
 * @note 使用场景:需要对数组进行排序,但是使用系统提供的排序方法无法满足需求时,可使用该方法自定义比较器函数进行排序。
 *       示例:假设有一个数组存储了多个人的信息,需要按照年龄从小到大排序,可以自定义比较器函数,然后调用该方法进行排序。
 */
- (NSArray<ObjectType> *)sortedArrayUsingFunction:(NSInteger (NS_NOESCAPE *)(ObjectType, ObjectType, void * _Nullable))comparator context:(nullable void *)context hint:(nullable NSData *)hint;

/**
 * @brief 使用指定的方法对数组进行排序
 *
 * @param comparator    比较器方法,用于比较数组中元素的大小关系
 *
 * @return 排序后的数组
 *
 * @note 使用场景:需要对数组进行排序,且使用系统提供的排序方法可以满足需求时,可使用该方法进行排序。
 *       示例:假设有一个数组存储了多个人的信息,需要按照姓名从A到Z排序,可以使用该方法并指定比较器方法。
 */
- (NSArray<ObjectType> *)sortedArrayUsingSelector:(SEL)comparator;

/**
 * @brief 返回指定范围内的数组元素
 *
 * @param range     指定的范围
 *
 * @return 指定范围内的数组元素组成的新数组
 *
 * @note 使用场景:需要获取数组中的一部分元素时,可使用该方法。
 *       示例:假设有一个数组存储了多个人的信息,需要获取其中前10个人的信息,可以使用该方法并指定范围。
 */
- (NSArray<ObjectType> *)subarrayWithRange:(NSRange)range;

/**
 * @brief 将数组写入指定的URL
 *
 * @param url       指定的URL
 * @param error     写入过程中发生的错误信息
 *
 * @return 写入是否成功
 *
 * @note 使用场景:需要将数组数据写入文件或网络传输时,可使用该方法。
 *       示例:假设有一个数组存储了多个人的信息,需要将其写入一个本地文件中,可以使用该方法并指定URL。
 */
- (BOOL)writeToURL:(NSURL *)url error:(NSError * *)error API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

/**
 * @brief 让数组中的所有对象执行指定的方法
 *
 * @param aSelector     指定的方法
 *
 * @note 使用场景:需要对数组中的所有对象执行某个方法时,可使用该方法。
 *       示例:假设有一个数组存储了多个人的信息,需要让其中所有人的年龄加1,可以使用该方法并指定方法。
 */
- (void)makeObjectsPerformSelector:(SEL)aSelector NS_SWIFT_UNAVAILABLE("Use enumerateObjectsUsingBlock: or a for loop instead");

/**
 * @brief 让数组中的所有对象执行指定的方法,并传递一个参数
 *
 * @param aSelector     指定的方法
 * @param argument      指定的参数
 *
 * @note 使用场景:需要对数组中的所有对象执行某个方法,并传递一个参数时,可使用该方法。
 *       示例:假设有一个数组存储了多个人的信息,需要让其中所有人的年龄加上一个指定的值,可以使用该方法并指定方法和参数。
 */
- (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(nullable id)argument NS_SWIFT_UNAVAILABLE("Use enumerateObjectsUsingBlock: or a for loop instead");

/**
 * @brief 返回指定索引集合中的数组元素
 *
 * @param indexes   指定的索引集合
 *
 * @return 指定索引集合中的数组元素组成的新数组
 *
 * @note 使用场景:需要获取数组中的部分元素时,可使用该方法。
 *       示例:假设有一个数组存储了多个人的信息,需要获取其中某几个人的信息,可以使用该方法并指定索引集合。
 */
- (NSArray<ObjectType> *)objectsAtIndexes:(NSIndexSet *)indexes;

/**
 * @brief 返回指定索引处的数组元素
 *
 * @param idx       指定的索引
 *
 * @return 指定索引处的数组元素
 *
 * @note 使用场景:需要获取数组中的某个元素时,可使用该方法。
 *       示例:假设有一个数组存储了多个人的信息,需要获取其中第一个人的信息,可以使用该方法并指定索引。
 */
- (ObjectType)objectAtIndexedSubscript:(NSUInteger)idx API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0));

/**
 * @brief 枚举数组中的所有元素,并执行指定的操作
 *
 * @param block     指定的操作,可以修改元素值或停止枚举
 *
 * @note 使用场景:需要对数组中的所有元素进行某种操作时,可使用该方法。
 *       示例:假设有一个数组存储了多个人的信息,需要对其中所有人的年龄加1,可以使用该方法并指定操作。
 */
- (void)enumerateObjectsUsingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

/**
 * @brief 枚举数组中的所有元素,并执行指定的操作
 *
 * @param opts      枚举选项,如并发枚举
 * @param block     指定的操作,可以修改元素值或停止枚举
 *
 * @note 使用场景:需要对数组中的所有元素进行某种操作时,可使用该方法。
 *       示例:假设有一个数组存储了多个人的信息,需要对其中所有人的年龄加1,可以使用该方法并指定操作。
 */
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

/**
 * @brief 枚举数组中指定索引集合的元素,并执行指定的操作
 *
 * @param s         指定的索引集合
 * @param opts      枚举选项,如并发枚举
 * @param block     指定的操作,可以修改元素值或停止枚举
 *
 * @note 使用场景:需要对数组中的部分元素进行某种操作时,可使用该方法。
 *       示例:假设有一个数组存储了多个人的信息,需要对其中某几个人的年龄加1,可以使用该方法并指定索引集合和操作。
 */
- (void)enumerateObjectsAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

/**
 * @brief 查找数组中满足条件的元素的下标
 *
 * @param predicate       判断条件的Block,返回BOOL值
 *
 * @return                返回第一个符合条件的元素的下标
 *
 * @discussion            使用场景:需要在数组中查找满足特定条件的元素的下标
 */
- (NSUInteger)indexOfObjectPassingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

/**
 * @brief 查找数组中满足条件的元素的下标
 *
 * @param opts             遍历选项
 * @param predicate        判断条件的Block,返回BOOL值
 *
 * @return                 返回第一个符合条件的元素的下标
 *
 * @discussion             使用场景:需要在数组中查找满足特定条件的元素的下标,并可以指定遍历选项
 */
- (NSUInteger)indexOfObjectWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

/**
 * @brief 查找数组中满足条件的元素的下标
 *
 * @param s                索引集合
 * @param opts             遍历选项
 * @param predicate        判断条件的Block,返回BOOL值
 *
 * @return                 返回第一个符合条件的元素的下标
 *
 * @discussion             使用场景:需要在数组中指定的索引集合中查找满足特定条件的元素的下标,并可以指定遍历选项
 */
- (NSUInteger)indexOfObjectAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

/**
 * @brief 查找数组中满足条件的元素的索引集合
 *
 * @param predicate        判断条件的Block,返回BOOL值
 *
 * @return                 返回符合条件的元素的索引集合
 *
 * @discussion             使用场景:需要在数组中查找满足特定条件的元素的索引集合
 */
- (NSIndexSet *)indexesOfObjectsPassingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

/**
 * @brief 查找数组中满足条件的元素的索引集合
 *
 * @param opts             遍历选项
 * @param predicate        判断条件的Block,返回BOOL值
 *
 * @return                 返回符合条件的元素的索引集合
 *
 * @discussion             使用场景:需要在数组中查找满足特定条件的元素的索引集合,并可以指定遍历选项
 */
- (NSIndexSet *)indexesOfObjectsWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

/**
 * @brief 在指定的索引集合中查找满足条件的元素的索引集合
 *
 * @param s                索引集合
 * @param opts             遍历选项
 * @param predicate        判断条件的Block,返回BOOL值
 *
 * @return                 返回符合条件的元素的索引集合
 *
 * @discussion             使用场景:需要在数组中指定的索引集合中查找满足特定条件的元素的索引集合,并可以指定遍历选项
 */
- (NSIndexSet *)indexesOfObjectsAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

/**
 * @brief 使用指定的比较器对数组进行排序
 *
 * @param cmptr            比较器
 *
 * @return                 返回排序后的数组
 *
 * @discussion             使用场景:需要对数组进行排序,使用指定的比较器
 */
- (NSArray<ObjectType> *)sortedArrayUsingComparator:(NSComparator NS_NOESCAPE)cmptr API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

/**
 * @brief 使用指定的比较器和选项对数组进行排序
 *
 * @param opts             排序选项
 * @param cmptr            比较器
 *
 * @return                 返回排序后的数组
 *
 * @discussion             使用场景:需要对数组进行排序,使用指定的比较器和排序选项
 */
- (NSArray<ObjectType> *)sortedArrayWithOptions:(NSSortOptions)opts usingComparator:(NSComparator NS_NOESCAPE)cmptr API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

// 二分查找选项
typedef NS_OPTIONS(NSUInteger, NSBinarySearchingOptions) {
    // 返回第一个相等的对象的索引。
    NSBinarySearchingFirstEqual = (1UL << 8),
    // 返回最后一个相等的对象的索引。
    NSBinarySearchingLastEqual = (1UL << 9),
    // 返回一个对象的索引,如果该对象不存在则返回应该插入该对象的索引。
    NSBinarySearchingInsertionIndex = (1UL << 10),
};

/**
 * @brief 在指定范围内使用二分查找算法查找指定对象,并返回其下标
 *
 * @param obj             要查找的对象
 * @param r               查找的范围
 * @param opts            查找选项
 * @param cmp             指定比较器
 *
 * @return                返回找到的对象的下标,如果没找到则返回NSNotFound
 *
 * @discussion           该方法使用二分查找算法,在指定的范围内查找指定的对象,如果找到则返回其下标,否则返回NSNotFound。使用该方法可以提高查找效率。
 *                       例如,如果你有一个已经排好序的数组,想要查找其中某个元素的下标,可以使用该方法来实现。
 *                       该方法要求传入一个比较器,用于比较两个对象的大小关系。比较器的格式为:^(id obj1, id obj2) { return NSComparisonResult; }。
 */
- (NSUInteger)indexOfObject:(ObjectType)obj
              inSortedRange:(NSRange)r
                    options:(NSBinarySearchingOptions)opts
            usingComparator:(NSComparator NS_NOESCAPE)cmp API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

/** 描述信息 */
@property(readonly, copy) NSString *description;
/** 获取数组中的第一个对象,如果数组为空则返回nil */
@property(nullable, nonatomic, readonly) ObjectType firstObject API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
/** 获取数组中的最后一个对象,如果数组为空则返回nil */
@property(nullable, nonatomic, readonly) ObjectType lastObject;
/** 返回一个用于对数组进行排序的提示数据 */
@property(readonly, copy) NSData *sortedArrayHint;

@end

@interface NSArray<ObjectType> (NSArrayCreation)

/**
 * @brief 创建并返回一个空的NSArray对象
 *
 * @return 一个空的NSArray对象
 */
+ (instancetype)array;

/**
 * @brief 创建并返回一个包含一个对象的NSArray对象
 *
 * @param anObject 一个要添加到新数组中的对象
 * @return 一个包含一个对象的NSArray对象
 *
 * 使用场景:创建一个包含一个特定对象的数组,例如一个字符串或数字
 * 举例:NSArray *array = [NSArray arrayWithObject:@"Hello"];
 */
+ (instancetype)arrayWithObject:(ObjectType)anObject;

/**
 * @brief 创建并返回一个包含count个对象的NSArray对象
 *
 * @param objects 一个指向要添加到新数组中的对象的C数组
 * @param cnt 要添加到新数组中的对象的数量
 * @return 一个包含count个对象的NSArray对象
 *
 * 使用场景:创建一个包含多个特定对象的数组,例如一组数字或字符串
 * 举例:NSString *strings[3] = {@"Hello", @"World", @"!"};
 *        NSArray *array = [NSArray arrayWithObjects:strings count:3];
 */
+ (instancetype)arrayWithObjects:(const ObjectType _Nonnull [_Nonnull])objects count:(NSUInteger)cnt;

/**
 * @brief 创建并返回一个包含变量数量的对象的NSArray对象
 *
 * @param firstObj 一个要添加到新数组中的对象
 * @param ... 其他要添加到新数组中的对象,以nil结尾
 * @return 一个包含变量数量的对象的NSArray对象
 *
 * 使用场景:创建一个包含不确定数量的特定对象的数组,例如一组不定数量的字符串
 * 举例:NSArray *array = [NSArray arrayWithObjects:@"Hello", @"World", nil];
 */
+ (instancetype)arrayWithObjects:(ObjectType)firstObj, ... NS_REQUIRES_NIL_TERMINATION;

/**
 * @brief 创建并返回一个包含另一个数组中的对象的NSArray对象
 *
 * @param array 要添加到新数组中的另一个数组
 * @return 一个包含另一个数组中的对象的NSArray对象
 *
 * 使用场景:创建一个包含另一个数组中的所有对象的数组,例如复制一个现有数组
 * 举例:NSArray *originalArray = [NSArray arrayWithObjects:@"Hello", @"World", nil];
 *        NSArray *newArray = [NSArray arrayWithArray:originalArray];
 */
+ (instancetype)arrayWithArray:(NSArray<ObjectType> *)array;

/**
 * @brief 创建并返回一个包含变量数量的对象的NSArray对象
 *
 * @param firstObj 一个要添加到新数组中的对象
 * @param ... 其他要添加到新数组中的对象,以nil结尾
 * @return 一个包含变量数量的对象的NSArray对象
 *
 * 使用场景:初始化一个包含不确定数量的特定对象的数组,例如一组不定数量的字符串
 * 举例:NSArray *array = [[NSArray alloc] initWithObjects:@"Hello", @"World", nil];
 */
- (instancetype)initWithObjects:(ObjectType)firstObj, ... NS_REQUIRES_NIL_TERMINATION;

/**
 * @brief 创建并返回一个包含另一个数组中的对象的NSArray对象
 *
 * @param array 要添加到新数组中的另一个数组
 * @return 一个包含另一个数组中的对象的NSArray对象
 *
 * 使用场景:初始化一个包含另一个数组中的所有对象的数组,例如复制一个现有数组
 * 举例:NSArray *originalArray = [NSArray arrayWithObjects:@"Hello", @"World", nil];
 *        NSArray *newArray = [[NSArray alloc] initWithArray:originalArray];
 */
- (instancetype)initWithArray:(NSArray<ObjectType> *)array;

/**
 * @brief 创建并返回一个包含另一个数组中的对象的NSArray对象
 *
 * @param array 要添加到新数组中的另一个数组
 * @param flag 如果为YES,则新数组将包含复制的对象;如果为NO,则新数组将包含原始对象的引用
 * @return 一个包含另一个数组中的对象的NSArray对象
 *
 * 使用场景:初始化一个包含另一个数组中的所有对象的数组,可以选择复制数组中的对象
 * 举例:NSArray *originalArray = [NSArray arrayWithObjects:@"Hello", @"World", nil];
 *        NSArray *newArray = [[NSArray alloc] initWithArray:originalArray copyItems:YES];
 */
- (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag;

/**
 * @brief 从指定URL创建并返回一个NSArray对象
 *
 * @param url 包含要添加到新数组中的对象的文件的URL
 * @param error 如果发生错误,则返回一个包含错误信息的NSError对象
 * @return 一个包含从指定URL加载的对象的NSArray对象
 *
 * 使用场景:从文件中加载一个数组,例如从磁盘上的文件中加载用户数据
 * 举例:NSURL *url = [NSURL fileURLWithPath:@"path/to/file"];
 *        NSError *error;
 *        NSArray *array = [[NSArray alloc] initWithContentsOfURL:url error:&error];
 */
- (nullable NSArray<ObjectType> *)initWithContentsOfURL:(NSURL *)url error:(NSError * *)error API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

/**
 * @brief 从指定URL创建并返回一个NSArray对象
 *
 * @param url 包含要添加到新数组中的对象的文件的URL
 * @param error 如果发生错误,则返回一个包含错误信息的NSError对象
 * @return 一个包含从指定URL加载的对象的NSArray对象
 *
 * 使用场景:从文件中加载一个数组,例如从磁盘上的文件中加载用户数据
 * 举例:NSURL *url = [NSURL fileURLWithPath:@"path/to/file"];
 *        NSError *error;
 *        NSArray *array = [NSArray arrayWithContentsOfURL:url error:&error];
 */
+ (nullable NSArray<ObjectType> *)arrayWithContentsOfURL:(NSURL *)url error:(NSError * *)error API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)) NS_SWIFT_UNAVAILABLE("Use initializer instead");

@end

API_AVAILABLE(macosx(10.15), ios(13.0), watchos(6.0), tvos(13.0))
NS_SWIFT_UNAVAILABLE("NSArray diffing methods are not available in Swift, use Collection.difference(from:) instead")
@interface NSArray<ObjectType> (NSArrayDiffing)

/**
 * @brief 计算当前数组与另一个数组之间的差异
 *
 * @param other             另一个数组
 * @param options           计算差异时的选项
 * @param block             用于比较两个对象是否相等的块
 *
 * @return 返回 NSOrderedCollectionDifference<ObjectType> 对象,表示当前数组与另一个数组之间的差异
 *
 * @note 该方法可以帮助我们快速比较两个数组之间的差异,例如我们可以使用该方法来比较两个版本的数据之间的差异,从而快速找出新增、删除、修改的数据。
 *
 * @example
 * NSArray *oldArray = @[@"A", @"B", @"C"];
 * NSArray *newArray = @[@"A", @"D", @"E"];
 * NSOrderedCollectionDifference *difference = [oldArray differenceFromArray:newArray withOptions:NSOrderedCollectionDifferenceCalculationNone usingEquivalenceTest:^BOOL(id obj1, id obj2) {
 *      return [obj1 isEqualToString:obj2];
 * }];
 * // difference.inserts = {@"D", @"E"}
 * // difference.deletes = {@"B", @"C"}
 * // difference.moves = {}
 * // difference.changes = {}
 */
- (NSOrderedCollectionDifference<ObjectType> *)differenceFromArray:(NSArray<ObjectType> *)other withOptions:(NSOrderedCollectionDifferenceCalculationOptions)options usingEquivalenceTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj1, ObjectType obj2))block;

/**
 * @brief 计算当前数组与另一个数组之间的差异
 *
 * @param other             另一个数组
 * @param options           计算差异时的选项
 *
 * @return 返回 NSOrderedCollectionDifference<ObjectType> 对象,表示当前数组与另一个数组之间的差异
 *
 * @note 该方法与上面的方法类似,只是没有提供自定义比较块的功能。
 *
 * @example
 * NSArray *oldArray = @[@"A", @"B", @"C"];
 * NSArray *newArray = @[@"A", @"D", @"E"];
 * NSOrderedCollectionDifference *difference = [oldArray differenceFromArray:newArray withOptions:NSOrderedCollectionDifferenceCalculationNone];
 * // difference.inserts = {@"D", @"E"}
 * // difference.deletes = {@"B", @"C"}
 * // difference.moves = {}
 * // difference.changes = {}
 */
- (NSOrderedCollectionDifference<ObjectType> *)differenceFromArray:(NSArray<ObjectType> *)other withOptions:(NSOrderedCollectionDifferenceCalculationOptions)options;

/**
 * @brief 计算当前数组与另一个数组之间的差异
 *
 * @param other             另一个数组
 *
 * @return 返回 NSOrderedCollectionDifference<ObjectType> 对象,表示当前数组与另一个数组之间的差异
 *
 * @note 该方法与上面的方法类似,只是使用默认的选项计算差异。
 *
 * @example
 * NSArray *oldArray = @[@"A", @"B", @"C"];
 * NSArray *newArray = @[@"A", @"D", @"E"];
 * NSOrderedCollectionDifference *difference = [oldArray differenceFromArray:newArray];
 * // difference.inserts = {@"D", @"E"}
 * // difference.deletes = {@"B", @"C"}
 * // difference.moves = {}
 * // difference.changes = {}
 */
- (NSOrderedCollectionDifference<ObjectType> *)differenceFromArray:(NSArray<ObjectType> *)other;

/**
 * @brief 根据给定的差异对象,生成新的数组
 *
 * @param difference        差异对象
 *
 * @return 返回 NSArray<ObjectType> 对象,表示根据差异对象生成的新数组
 *
 * @note 该方法可以帮助我们根据差异对象,生成新的数组,例如我们可以使用该方法来生成一个新的版本数据,从而实现数据的版本控制。
 *
 * @example
 * NSArray *oldArray = @[@"A", @"B", @"C"];
 * NSArray *newArray = @[@"A", @"D", @"E"];
 * NSOrderedCollectionDifference *difference = [oldArray differenceFromArray:newArray];
 * NSArray *resultArray = [oldArray arrayByApplyingDifference:difference];
 * // resultArray = @[@"A", @"D", @"E"]
 */
- (nullable NSArray<ObjectType> *)arrayByApplyingDifference:(NSOrderedCollectionDifference<ObjectType> *)difference;

@end

@interface NSArray<ObjectType> (NSDeprecated)

/**
 * @brief 获取指定类型对象数组中的所有元素
 *
 * @param objects 用于存放获取到的元素的数组
 *
 * @discussion 此方法用于获取指定类型对象数组中的所有元素,并将其存放到另一个数组中,方便后续处理。
 * 举例:NSArray *stringArray = @[@"hello", @"world"]; NSString *objects[2]; [stringArray getObjects:objects];
 * 上述代码就是将stringArray中的所有元素存放到了objects数组中。
 */
- (void)getObjects:(ObjectType _Nonnull __unsafe_unretained [_Nonnull])objects NS_SWIFT_UNAVAILABLE("Use 'as [AnyObject]' instead") API_DEPRECATED("Use -getObjects:range: instead", macos(10.0, 10.13), ios(2.0, 11.0), watchos(2.0, 4.0), tvos(9.0, 11.0));

/**
 * @brief 根据指定路径读取文件内容,并返回该文件内容所构成的数组
 *
 * @param path 文件路径
 *
 * @return 读取到的文件内容所构成的数组
 *
 * @discussion 此方法用于根据指定路径读取文件内容,并将其构成数组返回,方便后续处理。
 * 举例:NSArray *array = [NSArray arrayWithContentsOfFile:@"path/to/file"];
 * 上述代码就是将文件path/to/file中的内容读取出来,并构成一个数组返回。
 */
+ (nullable NSArray<ObjectType> *)arrayWithContentsOfFile:(NSString *)path API_DEPRECATED_WITH_REPLACEMENT("arrayWithContentsOfURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));

/**
 * @brief 根据指定URL读取文件内容,并返回该文件内容所构成的数组
 *
 * @param url 文件URL
 *
 * @return 读取到的文件内容所构成的数组
 *
 * @discussion 此方法用于根据指定URL读取文件内容,并将其构成数组返回,方便后续处理。
 * 举例:NSArray *array = [NSArray arrayWithContentsOfURL:url];
 * 上述代码就是将URL指向的文件中的内容读取出来,并构成一个数组返回。
 */
+ (nullable NSArray<ObjectType> *)arrayWithContentsOfURL:(NSURL *)url API_DEPRECATED_WITH_REPLACEMENT("arrayWithContentsOfURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));

/**
 * @brief 根据指定路径读取文件内容,并初始化一个数组对象
 *
 * @param path 文件路径
 *
 * @return 初始化后的数组对象
 *
 * @discussion 此方法用于根据指定路径读取文件内容,并将其构成数组初始化一个数组对象,方便后续处理。
 * 举例:NSArray *array = [[NSArray alloc] initWithContentsOfFile:@"path/to/file"];
 * 上述代码就是将文件path/to/file中的内容读取出来,并构成一个数组初始化为array对象。
 */
- (nullable NSArray<ObjectType> *)initWithContentsOfFile:(NSString *)path API_DEPRECATED_WITH_REPLACEMENT("initWithContentsOfURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));

/**
 * @brief 根据指定URL读取文件内容,并初始化一个数组对象
 *
 * @param url 文件URL
 *
 * @return 初始化后的数组对象
 *
 * @discussion 此方法用于根据指定URL读取文件内容,并将其构成数组初始化一个数组对象,方便后续处理。
 * 举例:NSArray *array = [[NSArray alloc] initWithContentsOfURL:url];
 * 上述代码就是将URL指向的文件中的内容读取出来,并构成一个数组初始化为array对象。
 */
- (nullable NSArray<ObjectType> *)initWithContentsOfURL:(NSURL *)url API_DEPRECATED_WITH_REPLACEMENT("initWithContentsOfURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));

/**
 * @brief 将数组内容写入到指定路径的文件中
 *
 * @param path 文件路径
 * @param useAuxiliaryFile 是否使用辅助文件
 *
 * @return 写入是否成功
 *
 * @discussion 此方法用于将数组内容写入到指定路径的文件中。
 * 举例:NSArray *array = @[@"hello", @"world"]; [array writeToFile:@"path/to/file" atomically:YES];
 * 上述代码就是将array中的内容写入到path/to/file指定的文件中,并且使用辅助文件。
 */
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile API_DEPRECATED_WITH_REPLACEMENT("writeToURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));

/**
 * @brief 将数组内容写入到指定URL的文件中
 *
 * @param url 文件URL
 * @param atomically 是否原子化
 *
 * @return 写入是否成功
 *
 * @discussion 此方法用于将数组内容写入到指定URL的文件中。
 * 举例:NSArray *array = @[@"hello", @"world"]; [array writeToURL:url atomically:YES];
 * 上述代码就是将array中的内容写入到URL指向的文件中,并且使用原子化方式。
 */
- (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)atomically API_DEPRECATED_WITH_REPLACEMENT("writeToURL:error:", macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));

@end

@interface NSMutableArray<ObjectType> : NSArray<ObjectType>

/**
 * @brief 向NSMutableArray中添加一个对象
 *
 * @param anObject        要添加的对象
 *
 * @discussion 该方法将一个对象添加到数组的末尾
 * 示例:NSMutableArray *array = [NSMutableArray array];
 *      [array addObject:@"apple"];
 *      [array addObject:@"banana"];
 *      [array addObject:@"orange"];
 *      NSLog(@"%@",array); // 输出:(apple, banana, orange)
 */
- (void)addObject:(ObjectType)anObject;

/**
 * @brief 在NSMutableArray中的指定位置插入一个对象
 *
 * @param anObject        要插入的对象
 * @param index           要插入的位置
 *
 * @discussion 该方法将一个对象插入到数组的指定位置
 * 示例:NSMutableArray *array = [NSMutableArray array];
 *      [array addObject:@"apple"];
 *      [array addObject:@"banana"];
 *      [array insertObject:@"orange" atIndex:1];
 *      NSLog(@"%@",array); // 输出:(apple, orange, banana)
 */
- (void)insertObject:(ObjectType)anObject atIndex:(NSUInteger)index;

/**
 * @brief 删除NSMutableArray中的最后一个对象
 *
 * @discussion 该方法将数组中的最后一个对象删除
 * 示例:NSMutableArray *array = [NSMutableArray arrayWithObjects:@"apple", @"banana", @"orange", nil];
 *      [array removeLastObject];
 *      NSLog(@"%@",array); // 输出:(apple, banana)
 */
- (void)removeLastObject;

/**
 * @brief 删除NSMutableArray中指定位置的对象
 *
 * @param index           要删除对象的位置
 *
 * @discussion 该方法将数组中指定位置的对象删除
 * 示例:NSMutableArray *array = [NSMutableArray arrayWithObjects:@"apple", @"banana", @"orange", nil];
 *      [array removeObjectAtIndex:1];
 *      NSLog(@"%@",array); // 输出:(apple, orange)
 */
- (void)removeObjectAtIndex:(NSUInteger)index;

/**
 * @brief 替换NSMutableArray中指定位置的对象
 *
 * @param index           要替换对象的位置
 * @param anObject        要替换的对象
 *
 * @discussion 该方法将数组中指定位置的对象替换为另一个对象
 * 示例:NSMutableArray *array = [NSMutableArray arrayWithObjects:@"apple", @"banana", @"orange", nil];
 *      [array replaceObjectAtIndex:1 withObject:@"grape"];
 *      NSLog(@"%@",array); // 输出:(apple, grape, orange)
 */
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(ObjectType)anObject;

/**
 * @brief 用默认容量创建NSMutableArray对象
 *
 * @return 返回创建的NSMutableArray对象
 *
 * @discussion 该方法用默认容量创建一个NSMutableArray对象
 * 示例:NSMutableArray *array = [[NSMutableArray alloc] init];
 */
- (instancetype)init NS_DESIGNATED_INITIALIZER;

/**
 * @brief 用指定容量创建NSMutableArray对象
 *
 * @param numItems        数组的容量
 *
 * @return 返回创建的NSMutableArray对象
 *
 * @discussion 该方法用指定容量创建一个NSMutableArray对象
 * 示例:NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:5];
 */
- (instancetype)initWithCapacity:(NSUInteger)numItems NS_DESIGNATED_INITIALIZER;

/**
 * @brief 用NSCoder对象创建NSMutableArray对象
 *
 * @param coder           NSCoder对象
 *
 * @return 返回创建的NSMutableArray对象
 *
 * @discussion 该方法用NSCoder对象创建一个NSMutableArray对象
 * 示例:NSMutableArray *array = [[NSMutableArray alloc] initWithCoder:coder];
 */
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

@end

@interface NSMutableArray<ObjectType> (NSExtendedMutableArray)

/**
 * @brief 向数组中添加另一个数组中的元素
 *
 * @param otherArray    另一个数组
 *
 * @discussion 使用场景:将一个数组中的元素添加到当前数组中,可以用于合并两个数组。
 */
- (void)addObjectsFromArray:(NSArray<ObjectType> *)otherArray;

/**
 * @brief 交换数组中指定位置的元素
 *
 * @param idx1      第一个位置
 * @param idx2      第二个位置
 *
 * @discussion 使用场景:交换数组中两个元素的位置,可以用于排序算法等场景。
 */
- (void)exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2;

/**
 * @brief 移除数组中的所有元素
 *
 * @discussion 使用场景:清空数组中的所有元素,可以用于释放内存等场景。
 */
- (void)removeAllObjects;

/**
 * @brief 移除数组中指定范围内的某个元素
 *
 * @param anObject  需要移除的元素
 * @param range     指定范围
 *
 * @discussion 使用场景:移除数组中指定范围内的某个元素,可以用于去重、筛选等场景。
 */
- (void)removeObject:(ObjectType)anObject inRange:(NSRange)range;

/**
 * @brief 移除数组中某个元素
 *
 * @param anObject  需要移除的元素
 *
 * @discussion 使用场景:移除数组中某个元素,可以用于去重、筛选等场景。
 */
- (void)removeObject:(ObjectType)anObject;

/**
 * @brief 移除数组中指定范围内与某个元素相同的元素
 *
 * @param anObject  需要移除的元素
 * @param range     指定范围
 *
 * @discussion 使用场景:移除数组中指定范围内与某个元素相同的元素,可以用于去重、筛选等场景。
 */
- (void)removeObjectIdenticalTo:(ObjectType)anObject inRange:(NSRange)range;

/**
 * @brief 移除数组中与某个元素相同的元素
 *
 * @param anObject  需要移除的元素
 *
 * @discussion 使用场景:移除数组中与某个元素相同的元素,可以用于去重、筛选等场景。
 */
- (void)removeObjectIdenticalTo:(ObjectType)anObject;

/**
 * @brief 移除数组中指定下标的多个元素
 *
 * @param indices   需要移除的元素的下标数组
 * @param cnt       下标数组中元素的个数
 *
 * @deprecated 该方法已不支持
 *
 * @discussion 使用场景:移除数组中多个元素,可以用于去重、筛选等场景。
 */
- (void)removeObjectsFromIndices:(NSUInteger *)indices numIndices:(NSUInteger)cnt API_DEPRECATED("Not supported", macos(10.0,10.6), ios(2.0,4.0), watchos(2.0,2.0), tvos(9.0,9.0));

/**
 * @brief 移除数组中另一个数组中的所有元素
 *
 * @param otherArray    另一个数组
 *
 * @discussion 使用场景:移除数组中另一个数组中的所有元素,可以用于筛选、去重等场景。
 */
- (void)removeObjectsInArray:(NSArray<ObjectType> *)otherArray;

/**
 * @brief 移除数组中指定范围内的所有元素
 *
 * @param range     指定范围
 *
 * @discussion 使用场景:移除数组中指定范围内的所有元素,可以用于筛选、去重等场景。
 */
- (void)removeObjectsInRange:(NSRange)range;

/**
 * @brief 用另一个数组中指定范围的元素替换数组中指定范围内的元素
 *
 * @param range         指定范围
 * @param otherArray    另一个数组
 * @param otherRange    另一个数组中指定范围
 *
 * @discussion 使用场景:用另一个数组中指定范围的元素替换数组中指定范围内的元素,可以用于合并数组等场景。
 */
- (void)replaceObjectsInRange:(NSRange)range withObjectsFromArray:(NSArray<ObjectType> *)otherArray range:(NSRange)otherRange;

/**
 * @brief 用另一个数组中的元素替换数组中指定范围内的元素
 *
 * @param range         指定范围
 * @param otherArray    另一个数组
 *
 * @discussion 使用场景:用另一个数组中的元素替换数组中指定范围内的元素,可以用于合并数组等场景。
 */
- (void)replaceObjectsInRange:(NSRange)range withObjectsFromArray:(NSArray<ObjectType> *)otherArray;

/**
 * @brief 使用另一个数组中的元素替换当前数组中的所有元素
 *
 * @param otherArray    另一个数组
 *
 * @discussion 使用场景:使用另一个数组中的元素替换当前数组中的所有元素,可以用于合并数组、更新数据等场景。
 */
- (void)setArray:(NSArray<ObjectType> *)otherArray;

/**
 * @brief 使用指定的比较函数对数组进行排序
 *
 * @param compare   比较函数
 * @param context   上下文
 *
 * @discussion 使用场景:使用指定的比较函数对数组进行排序,可以用于排序算法等场景。
 */
- (void)sortUsingFunction:(NSInteger (NS_NOESCAPE *)(ObjectType, ObjectType, void * _Nullable))compare context:(nullable void *)context;

/**
 * @brief 使用指定的选择器对数组进行排序
 *
 * @param comparator    选择器
 *
 * @discussion 使用场景:使用指定的选择器对数组进行排序,可以用于排序算法等场景。
 */
- (void)sortUsingSelector:(SEL)comparator;

/**
 * @brief 在指定的下标处插入多个元素
 *
 * @param objects   需要插入的元素数组
 * @param indexes   需要插入的元素的下标数组
 *
 * @discussion 使用场景:在指定的下标处插入多个元素,可以用于插入数据等场景。
 */
- (void)insertObjects:(NSArray<ObjectType> *)objects atIndexes:(NSIndexSet *)indexes;

/**
 * @brief 移除指定下标的多个元素
 *
 * @param indexes   需要移除的元素的下标数组
 *
 * @discussion 使用场景:移除指定下标的多个元素,可以用于去重、筛选等场景。
 */
- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;

/**
 * @brief 用指定的元素替换指定下标的多个元素
 *
 * @param indexes   需要替换的元素的下标数组
 * @param objects   需要替换的元素数组
 *
 * @discussion 使用场景:用指定的元素替换指定下标的多个元素,可以用于更新数据等场景。
 */
- (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withObjects:(NSArray<ObjectType> *)objects;

/**
 * @brief 使用下标操作符设置指定下标的元素
 *
 * @param obj   需要设置的元素
 * @param idx   下标
 *
 * @discussion 使用场景:使用下标操作符设置指定下标的元素,可以用于更新数据等场景。
 */
- (void)setObject:(ObjectType)obj atIndexedSubscript:(NSUInteger)idx API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0));

/**
 * @brief 使用指定的比较器对数组进行排序
 *
 * @param cmptr 比较器
 *
 * @discussion 使用场景:使用指定的比较器对数组进行排序,可以用于排序算法等场景。
 */
- (void)sortUsingComparator:(NSComparator NS_NOESCAPE)cmptr API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

/**
 * @brief 使用指定的选项和比较器对数组进行排序
 *
 * @param opts  排序选项
 * @param cmptr 比较器
 *
 * @discussion 使用场景:使用指定的选项和比较器对数组进行排序,可以用于排序算法等场景。
 */
- (void)sortWithOptions:(NSSortOptions)opts usingComparator:(NSComparator NS_NOESCAPE)cmptr API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

@end

@interface NSMutableArray<ObjectType> (NSMutableArrayCreation)

/**
 * @brief 根据所需容量创建一个NSMutableArray对象
 *
 * @param numItems        所需容量
 *
 * @return NSMutableArray对象
 *
 * @discussion 可以使用此方法在创建NSMutableArray对象时指定其容量,以提高其性能。例如,如果我们需要添加1000个元素到数组中,那么使用此方法创建一个容量为1000的数组,将比使用默认容量创建一个数组更加高效。
 */
+ (instancetype)arrayWithCapacity:(NSUInteger)numItems;

/**
 * @brief 根据指定文件路径读取文件内容并创建一个NSMutableArray对象
 *
 * @param path        文件路径
 *
 * @return NSMutableArray对象,如果读取失败则返回nil
 *
 * @discussion 可以使用此方法读取指定文件中的内容,并将其转换为NSMutableArray对象。例如,我们可以使用此方法读取一个存储学生信息的文件,然后将其转换为NSMutableArray对象,方便后续对学生信息的处理和操作。
 */
+ (nullable NSMutableArray<ObjectType> *)arrayWithContentsOfFile:(NSString *)path;

/**
 * @brief 根据指定URL读取文件内容并创建一个NSMutableArray对象
 *
 * @param url        文件的URL
 *
 * @return NSMutableArray对象,如果读取失败则返回nil
 *
 * @discussion 可以使用此方法读取指定URL中的内容,并将其转换为NSMutableArray对象。例如,我们可以使用此方法从网络上读取一个存储用户评论的文件,然后将其转换为NSMutableArray对象,以便在应用程序中显示这些评论。
 */
+ (nullable NSMutableArray<ObjectType> *)arrayWithContentsOfURL:(NSURL *)url;

/**
 * @brief 根据指定文件路径读取文件内容并创建一个NSMutableArray对象
 *
 * @param path        文件路径
 *
 * @return NSMutableArray对象,如果读取失败则返回nil
 *
 * @discussion 可以使用此方法读取指定文件中的内容,并将其转换为NSMutableArray对象。例如,我们可以使用此方法读取一个存储学生信息的文件,然后将其转换为NSMutableArray对象,方便后续对学生信息的处理和操作。
 */
- (nullable NSMutableArray<ObjectType> *)initWithContentsOfFile:(NSString *)path;

/**
 * @brief 根据指定URL读取文件内容并创建一个NSMutableArray对象
 *
 * @param url        文件的URL
 *
 * @return NSMutableArray对象,如果读取失败则返回nil
 *
 * @discussion 可以使用此方法读取指定URL中的内容,并将其转换为NSMutableArray对象。例如,我们可以使用此方法从网络上读取一个存储用户评论的文件,然后将其转换为NSMutableArray对象,以便在应用程序中显示这些评论。
 */
- (nullable NSMutableArray<ObjectType> *)initWithContentsOfURL:(NSURL *)url;

@end

API_AVAILABLE(macosx(10.15), ios(13.0), watchos(6.0), tvos(13.0))
NS_SWIFT_UNAVAILABLE("NSMutableArray diffing methods are not available in Swift")
@interface NSMutableArray<ObjectType> (NSMutableArrayDiffing)

/**
 * @brief 应用NSOrderedCollectionDifference<ObjectType>类型的差异到NSMutableArray中
 *
 * @param difference        NSOrderedCollectionDifference<ObjectType>类型的差异
 *
 * 使用场景:
 * 当需要对两个有序集合进行比较,并获取它们之间的差异时,可以使用NSOrderedCollectionDifference类来获取差异信息。而这个方法则可以将获取到的差异信息应用到NSMutableArray中,以便我们对数据进行操作。
 *
 * 示例:
 * NSMutableArray *originalArray = [NSMutableArray arrayWithObjects:@"a", @"b", @"c", nil];
 * NSMutableArray *newArray = [NSMutableArray arrayWithObjects:@"a", @"b", @"d", @"e", nil];
 * NSOrderedCollectionDifference *difference = [originalArray differenceFromArray:newArray];
 * [originalArray applyDifference:difference];
 * //此时originalArray的内容为:@[@"a", @"b", @"d", @"e"]
 */
- (void)applyDifference:(NSOrderedCollectionDifference<ObjectType> *)difference;

@end
posted @ 2018-12-20 21:53  CH520  阅读(330)  评论(0编辑  收藏  举报