NSArray&NSMutableArray常用操作梳理

NSArray and its subclass NSMutableArray manage ordered collections of objects called arrays.

NSArray creates static arrays, and NSMutableArray creates dynamic arrays. 

You can use arrays when you need an ordered collection of objects.


NSArray 用于保存对象的有序集合,但只能保存 OC 对象(继承自 NSObject 的 interface)。由于 Objective-C++ 是动态定型(dynamically typed),继承自NSObject 的 interface type cannot be statically allocated。因此 NSArray 本质上保存的是id,即 NSObject* 泛型指针。最新版 SDK 头文件已将数组元素声明为支持 <ObjectType> 协议的类型,数组作为参数则声明为 NSArray<ObjectType>。

Cocoa 的 NSArray 是基于 C 底层 CFArray/CFArrayRef 实现的,NSArray 可以看做是一个 CFArrayRef 的 Wrapper类。

__NSArrayIImmutable)是NSArray的真正类型(_internal),__NSArrayMMutable是NSMutableArray的真正类型(_internal)

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

原生数据类型(Native Data Type: int,char,double,etc)不能直接作为 NSArray 元素,它们必须通过装箱(boxing)成 NSNumber、NSString 或 NSValue 等 OC 对象才能纳入 OC 数组存储。

在苹果 WWDC2012 大会上介绍了大量 Objective-C 的新特性,其中有一点就是Objective-C Literals(参考123),它允许你在XCode 4.4/LLVM Compiler 4.0/iOS 6及以上平台方便地基于字面量定义数字、数组和字典常量对象

Three new features were introduced into clang at the same time: 
- NSNumber Literals provide a syntax for creating NSNumber from scalar literal expressions;
- Collection Literals provide a short-hand for creating arrays and dictionaries; 
- Object Subscripting provides a way to use subscripting with Objective-C objects. 

Users of Apple compiler releases can use these features starting with the Apple LLVM Compiler 4.0. 
Users of open-source LLVM.org compiler releases can use these features starting with clang v3.1.

APPLE LLVM CLANG 前端(参考LLVM 之 ClangLLVM 与 Clang)支持字面语法,它使用简化符号 @ 声明编译器指令来定义对象,类似 java5 提供的 auto boxing 功能。这虽然是一个语法糖,但对提高写代码效率帮助很大。


以下代码片段基于字面量语法快捷初始化数组(NSArray):

NSNumber* noChar    = @'X';     // [NSNumber numberWithChar:'X'];
NSNumber* noInt     = @12345;   // [NSNumber numberWithInt:12345];
NSNumber* noLL      = @12345ll; // [NSNumber numberWithLong:12345];
NSNumber* noUL      = @12345ul; // [NSNumber numberWithLong:12345];
NSNumber* noFloat   = @123.45f; // [NSNumber numberWithFloat:123.45f];
NSNumber* noDouble  = @123.45;  // [NSNumber numberWithDouble:123.45];
NSNumber* noBool    = @YES;     // [NSNumber numberWithBool:YES];
NSInteger year      = 2016;     // sizeof(NSInteger)=8 under __LP64__
NSNumber* noInteger = @(year);  // [NSNumber numberWithLong:2016];
NSString* strMonth  = @"May"

NSArray* array = @[noInteger, strMonth, noBool, noUL, noChar]; // 都是NSObject对象
NSLog(@"array = %@", array);

@(var):动态评估封装的表达,并返回基于变量var值的合适的对象常量。例如:const char*返回NSString,int返回NSNumber,etc。

 1.创建初始化(NSArrayCreation

Each object in array simply receives a retain message when it is added to the returned array using initWith*/arrayWith* method.

After an immutable array has been initialized in the following way, it cannot be modified.

1.1 Initializing an Array(NS_DESIGNATED_INITIALIZER)

// Initializes a newly allocated array. Not recommended for immutable array as  it's empty!
- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithObjects:(const ObjectType[])objects count:(NSUInteger)cnt NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithObjects:(ObjectType)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initWithArray:(NSArray<ObjectType> *)array;
// If YES, each object in array receives a copyWithZone: message to create a copy of the object instead of the retain message.
- (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag;
以下是比较常用的初始化方法:

- (instancetype)initWithObjects:(ObjectType)firstObj, ... NS_REQUIRES_NIL_TERMINATION;

1.2 Creating an Array(autorelease)

// Creates and returns an empty array. This method is used by mutable subclasses of NSArray.
+ (instancetype)array;
+ (instancetype)arrayWithObject:(ObjectType)anObject;
+ (instancetype)arrayWithObjects:(const ObjectType[])objects count:(NSUInteger)cnt; // initWithObjects:count:
+ (instancetype)arrayWithObjects:(ObjectType)firstObj, ...NS_REQUIRES_NIL_TERMINATION; // initWithObjects:count:
+ (instancetype)arrayWithArray:(NSArray<ObjectType> *)array; // initWithArray:

以下是比较常用的类方法便利构造方法:

+ (instancetype)arrayWithObjects:(ObjectType)firstObj, ...NS_REQUIRES_NIL_TERMINATION; // initWithObjects:count:

+ (instancetype)arrayWithArray:(NSArray<ObjectType> *)array; // initWithArray:

2.访问数组(Querying

2.1 数组描述

@property (readonly,copy)NSString *description;

例如以下代码可以在调试时打印数组(中各个元素的描述):

    NSArray* array = [NSArray arrayWithObjects:@"e0",@"e1",@"e2",@"e3",@"e4",@"e5",@"e6",nil];
    NSLog(@"array = %@", array);
    NSLog(@"array = %@", array.description);

2.2 数组大小

//返回数组所包含的元素(NSObject对象)个数(The number of objects in the array.)
@property (readonly) NSUInteger count;

可以基于array.count对数组进行判空:如果array.count=0,则表示数组对象为nil或不包含任何元素。

说明:在Objective-C中向nil发送消息不会崩溃的。

2.3 数组元素

// 返回数组第一个/最后一个元素。
// If the array is empty, returns nil.
@property (nullable, nonatomic, readonly) ObjectType firstObject NS_AVAILABLE(10_6, 4_0);
@property (nullable, nonatomic, readonly) ObjectType lastObject;

// 判断数组是否包含某个元素(按值查询)。
// YES if anObject is present in the array, otherwise NO.
- (BOOL)containsObject:(ObjectType)anObject;

// 返回数组指定索引位置的元素,索引范围为[0, count-1]
// Returns the object located at the specified index.
- (ObjectType)objectAtIndex:(NSUInteger)index;

// operator []:相当于中括号下标访问格式(array[index]),返回指定索引元素。等效于 objectAtIndex。
// Returns the object at the specified index.
- (ObjectType)objectAtIndexedSubscript:(NSUInteger)idx NS_AVAILABLE(10_8, 6_0);

// 返回数组指定索引集的元素组成的子数组
// Returns an array containing the objects in the array at the indexes specified by a given index set.
- (NSArray<ObjectType> *)objectsAtIndexes:(NSIndexSet *)indexes;
 
 
  • objectAtIndex:方法用于快速返回指定索引位置的元素,也可直接使用 operator [] 下标格式访问firstObject 和 lastObject 属性用于快捷访问数组的首、尾元素。
  • containsObject:方法用于按值搜索查询数组是否包含某个元素,用于一些预判防止重复 addObject 的场合。

可以基于 array.firstObject 对数组进行判空:如果第一个元素都为空,那么数组无疑为空(数组对象为nil或不包含任何元素)。

以下代码获取第2、4、6个元素子数组:

    NSMutableIndexSet* indexSet = [NSMutableIndexSet indexSet];
    [indexSet addIndex:1];
    [indexSet addIndex:3];
    [indexSet addIndex:5];
    NSArray* subArray = [array objectsAtIndexes:indexSet];
    NSLog(@"subArray= %@", subArray);
等效于:

// objectAtIndexedSubscript
NSArray* subArray = [NSArray arrayWithObjects:[array objectAtIndex:1], [array objectAtIndex:3], [array objectAtIndex:5], nil];

// <span class="s1">operator</span><span class="s2"> [] </span>下标写法
NSArray* subArray = [NSArray arrayWithObjects:array[1], array[3], array[5], nil];

// 简化字面量语法
NSArray* subArray = @[array[1], array[3], array[5]];

2.4遍历数组

(1)索引遍历

    // 倒序:for (NSInteger index=array.count-1; index>=0; index--)
    for (NSUInteger index=0; index<array.count; index++)
    {
        NSLog(@"array[%zd] = %@", index, [array objectAtIndex:index]); // array[index]
    }

(2)枚举遍历

    // 倒序:reverseObjectEnumerator
    NSEnumerator* enumerator = [array objectEnumerator];
    id e = nil;
    while (e = [enumerator nextObject])
    {
        NSLog(@"e = %@", e);
    }
   
    /*
    for (id e in enumerator) {
        NSLog(@"e = %@",e);
    }
    */

使用代码块传递遍历操作:

- (void)enumerateObjectsUsingBlock:(void (^)(id obj,NSUInteger idx,BOOL *stop))block NS_AVAILABLE(10_6,4_0);

    // 示例1:枚举遍历
    [array enumerateObjectsUsingBlock:^ (id obj, NSUInteger idx, BOOL *stop){
        NSLog(@"obj = %@", obj);
    }];
    
    // 示例2:枚举遍历,遇到符合条件的元素(obj=array[idx])即退出遍历。
    [array enumerateObjectsUsingBlock:^ (id obj, NSUInteger idx, BOOL *stop){
        if ([obj isEqualToString:@"e3"]) {
            *stop = YES; // 中止遍历, break
        } else {
            *stop = NO; // 继续遍历,continue
        }
    }];

以上版本默认是顺序同步遍历,另外一个版本可以指定 NSEnumerationOptions 参数:

typedefNS_OPTIONS(NSUInteger, NSEnumerationOptions) {
    NSEnumerationConcurrent = (1UL <<0),// block并发
    NSEnumerationReverse = (1UL <<1),//倒序
};

(3)快速遍历

    for (id e in array) {
        NSLog(@"e = %@", e);
    }

3.查询数组(Indexing

3.1 indexOfObject(IdenticalTo)

// 在数组(或指定范围)中,测试指定的对象是否在数组中(按值查询)
- (NSUInteger)indexOfObject:(ObjectType)anObject; // 同containsObject
- (NSUInteger)indexOfObject:(ObjectType)anObject inRange:(NSRange)range;
// 测试指定的对象是否在数组中(按指针查询)
- (NSUInteger)indexOfObjectIdenticalTo:(ObjectType)anObject;
- (NSUInteger)indexOfObjectIdenticalTo:(ObjectType)anObject inRange:(NSRange)range;

3.2 indexOfObject(s)PassingTest

使用代码块传递遍历操作过滤条件:

//查找数组中第一个符合条件的对象(代码块过滤),返回对应索引
- (NSUInteger)indexOfObjectPassingTest:(BOOL (^)(id obj,NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6,4_0);

以下代码用于获取值等于@"e3"的元素索引:

    NSUInteger index = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        if ([obj isEqualToString:@"e3"]) {
            return YES;
            *stop = YES; // 中止遍历,break
        } else {
            *stop = NO; // 继续遍历,continue
        }
    }];

查找数组中所有符合条件的对象(代码块过滤),返回对应索引集合:

- (NSIndexSet *)indexesOfObjectsPassingTest:(BOOL (^)(id obj,NSUInteger idx, BOOL *stop)) predicate NS_AVAILABLE(10_6,4_0);


以上indexesOfObjectPassingTest/ indexesOfObjectsPassingTest版本默认是顺序同步遍历,它们都有另外可以指定NSEnumerationOptions参数的扩展版本。

indexOfObjectAtIndexes:options:passingTest:和indexOfObjectsAtIndexes:options:passingTest:则是指定索引集合内查找并返回索引(集合)。

3.3 firstObjectCommonWithArray

// 查找与给定数组中第一个相同的对象(按值)
// Returns the first object contained in the receiving array that’s equal to an object in another given array.
- (nullable ObjectType)firstObjectCommonWithArray:(NSArray<ObjectType> *)otherArray;

示例:

    id fo = [array firstObjectCommonWithArray:subArray];
    NSLog(@"fo= %@", fo); // e1

4.衍生数组(Deriving

4.1 subArray

// 返回指定范围(起始索引、长度)的子数组
// Returns a new array containing the receiving array’s elements that fall within the limits specified by a given range.
- (NSArray<ObjectType> *)subarrayWithRange:(NSRange)range;
以下代码获取数组前一半子数组:

    //return the first half of the whole array
    NSArray* subArray = [array subarrayWithRange:NSMakeRange(0,array.count/2)];
    NSLog(@"subArray= %@", subArray);

4.2 arrayByAdding

// 在当前数组追加元素或数组,并返回新数组对象
// Returns a new array that is a copy of the receiving array with a given object(the objects contained in another array) added to the end.
- (NSArray<ObjectType> *) arrayByAddingObject:(id)anObject;
- (NSArray<ObjectType> *) arrayByAddingObjectsFromArray:(NSArray<ObjectType> *)otherArray;

5.可变数组(NSMutableArray)

5.1 Initializing an Array(NS_DESIGNATED_INITIALIZER)

除了继承NSArray基本的init,还增加了以下指定初始化函数

- (instancetype)initWithCapacity:(NSUInteger)numItemsNS_DESIGNATED_INITIALIZER;

5.2 addObject

//尾部追加一个元素
- (void)addObject:(ObjectType)anObject;
//尾部追加一个数组
- (void)addObjectsFromArray:(NSArray<ObjectType> *)otherArray;

5.3 insertObject

//在指定索引处插入一个元素,原来的元素后移
// index取值范围=[0, count],index=count时相当于addObject
- (void)insertObject:(ObjectType)anObject atIndex:(NSUInteger)index;
//在指定索引集合处插入一个数组元素,相当于批次insertObject: atIndex:
- (void)insertObjects:(NSArray<ObjectType> *)objects atIndexes:(NSIndexSet*)indexes;

5.4 exchangeObject/replaceObject

//交换对应索引位置的元素(索引必须有效)
- (void)exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2;

//替换对应索引位置的元素(索引必须有效)
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(ObjectType)anObject;
//替换对应索引集合位置的元素,相当于批次replaceObjectAtIndex: withObject:
- (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withObjects:(NSArray<ObjectType> *)objects;

//等效于replaceObjectAtIndex,支持中括号下标格式(array[index])赋值替换。
// index取值范围=[0, count],index=count时相当于addObject
- (void)setObject:(ObjectType)obj atIndexedSubscript:(NSUInteger)idx NS_AVAILABLE(10_8,6_0);
//等效于先removeAllObjects后addObjectsFromArray
- (void)setArray:(NSArray<ObjectType> *)otherArray;

5.5 removeObject 

- (void)removeLastObject;
//删除对应索引位置/范围的元素(索引/范围必须有效)
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;
- (void)removeObjectsInRange:(NSRange)range;
//有则删除
- (void)removeObject:(ObjectType)anObject;
- (void)removeObject:(ObjectType)anObject inRange:(NSRange)range;
- (void)removeObjectsInArray:(NSArray<ObjectType> *)otherArray; // 对照 removeObjectsAtIndexes
- (void)removeAllObjects; // Empties the array of all its elements.

NSMutableArray 的 addObject 会对纳入管理的 obj 发送retain 消息。

NSMutableArray 的 removeObject 会对 obj 发送release 消息(解除引用关系)。

NSMutableArray 的 releaseremoveAllObjects 会对所有元素发送release 消息。

6.数组排序(Sorting

6.1 Using Selector(-[NSArray(NSExtendedArray) sortedArrayUsingSelector:])

针对 NSDictionary 或自定义的数据模型 FileModel 可自定义实现 compare: 方法,然后将其作为分类 SEL( comparator

@interface FileModel : NSObject
{
    UInt64      _time; // uint64_t
    NSString*   _cnName;
    NSString*   _enName;
}

@property (nonatomic, assign) UInt64 time;
@property (nonatomic, strong) NSString* cnName;
@property (nonatomic, strong) NSString* enName;

-(NSComparisonResult)compare:(FileModel*)otherFile;

@end

@implementation FileModel

-(NSComparisonResult)compare:(FileModel*)otherFile
{
    // only if self.time <= otherFile.time, it will return NSOrderedAscending=-1(!YES,NO),升序。
    // return self.time > otherFile.time;
    
    // if otherFile.time > self.time, return NSOrderedAscending,升序。
    // return [@(self.time) compare:@(otherFile.time)];
    
    // only if self.time >= otherFile.time, it will return NSOrderedAscending=-1(!YES,NO),降序。
    // return self.time < otherFile.time;
    
    // if self.time > otherFile.time, return NSOrderedAscending,降序。
    return [@(otherFile.time) compare:@(self.time)];
}

@end
以下按照文件列表( NSMutableArray < FileModel *>* fileList )的时间戳进行降序排列,从近到远展示文件:
        // Returns an array that lists the receiving array’s elements in ascending order,
        // as determined by the comparison method specified by a given selector.
        // The new array contains references to the receiving array’s elements, not copies of them.
        // The comparator message is sent to each object in the array and has as its single argument another object in the array.
        NSLog(@"-[NSArray(NSExtendedArray) sortedArrayUsingSelector:]");
        NSArray* sortedArrayUsingSelector = [fileList sortedArrayUsingSelector:@selector(compare:)];
        NSEnumerator* enumerator = [sortedArrayUsingSelector objectEnumerator];
        FileModel* file = nil;
        while (file = [enumerator nextObject]) {
            NSLog(@"{%llu, %@, %@}", file.time, file.enName, file.cnName);
        }
        NSLog(@"--------------------------------------------------");

6.2 Using Descriptor(-[NSArray(NSSortDescriptorSorting) sortedArrayUsingDescriptors:])

可基于属性 key path 定义  NSSortDescriptor 对象,按照主、次 key 对数组进行多维排序。例如,以下基于文件的中文名称排序;当中文名称一样时,基于英文名称排序。

        // Returns a copy of the receiving array sorted as specified by a given array of sort descriptors.
        // The first descriptor specifies the primary key path to be used in sorting the receiving array’s contents.
        // Any subsequent descriptors are used to further refine sorting of objects with duplicate values.
        NSSortDescriptor* primaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"cnName" ascending:YES];
        NSSortDescriptor* secondaryDescriptor = [[NSSortDescriptor alloc] initWithKey:@"enName" ascending:YES];
        NSArray* sortDescriptors = @[primaryDescriptor, secondaryDescriptor];
        NSArray* sortedArrayUsingDescriptors = [fileList sortedArrayUsingDescriptors:sortDescriptors];
        
        NSLog(@"-[NSArray(NSSortDescriptorSorting) sortedArrayUsingDescriptors:]");
        [sortedArrayUsingDescriptors enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            FileModel* file = obj;
            NSLog(@"{%@, %@, %llu}", file.cnName, file.enName, file.time);
        }];
        NSLog(@"--------------------------------------------------");

6.3 Using Comparator(-[NSMutableArray(NSExtendedMutableArray) sortUsingComparator:])

若数据模型的属性可基于 NSComparator (即 6.1 中的分类 SEL[comparator])进行排序,则可调用 sortUsingComparator 方法直接对数组进行排序

        // Sorts the receiver in ascending order using the comparison method
        // specified by a given NSComparator block.
        [fileList sortUsingComparator:^NSComparisonResult(id  _Nonnull f1, id  _Nonnull f2) {
            FileModel* firstFile = f1;
            FileModel* secondFile = f2;
            // return firstFile.time < secondFile.time; // NSOrderedAscending
            return [@(secondFile.time) compare:@(firstFile.time)];
        }];
        
        NSLog(@"-[NSMutableArray(NSExtendedMutableArray) sortUsingComparator:]");
        for (FileModel* file in fileList) {
            NSLog(@"{%llu, %@, %@}", file.time, file.enName, file.cnName);
        }
相对于 SEL 和 Descriptor,该方法直接将数组内部的元素排好序,而非返回 copy,使用时可根据需要选择。

7.常用数组

最后,本节简要梳理 iOS 日常开发使用最频繁的基础库(Foundation.framework)和界面库(UIKit.framework)中的数组呈现,透过其开放出来的数组存储聚合,也能管中窥豹,略览组件基础类的内部组织构建和管理功能要点。

7.1 复合构成元素(NSBundle、NSThread)


// NSBundle

@interface NSBundle : NSObject
+ (NSBundle *)mainBundle;
// Returns an array of all the application’s non-framework bundles.
+ (NSArray<NSBundle *> *)allBundles;
// Returns an array of all of the application’s bundles that represent frameworks.
+ (NSArray<NSBundle *> *)allFrameworks;
@end


// NSThread

@interface NSThread : NSObject 
// Returns an array containing the call stack return addresses.
+ (NSArray<NSNumber *> *)callStackReturnAddresses NS_AVAILABLE(10_5, 2_0);
// Returns an array containing the call stack symbols.
// Each element is an NSString object with a value in a format determined by the backtrace_symbols() function. 
+ (NSArray<NSString *> *)callStackSymbols NS_AVAILABLE(10_6, 4_0);
@end

7.2 操作队列结构(NSOperationQueue)


// NSOperation

NS_CLASS_AVAILABLE(10_5, 2_0)
@interface NSOperation : NSObject
// An array of the operation objects that must finish executing before the current object can begin executing. 
@property (readonly, copy) NSArray<NSOperation *> *dependencies;
@end

NS_CLASS_AVAILABLE(10_6, 4_0)
@interface NSBlockOperation : NSOperation
+ (instancetype)blockOperationWithBlock:(void (^)(void))block;
- (void)addExecutionBlock:(void (^)(void))block;
// return the blocks associated with the receiver.
// The blocks in this array are copies of those originally added using the addExecutionBlock: method.
@property (readonly, copy) NSArray<void (^)(void)> *executionBlocks;
@end

NS_CLASS_AVAILABLE(10_5, 2_0)
@interface NSOperationQueue : NSObject
- (void)addOperation:(NSOperation *)op;
// return an array of the operations currently in the queue.
@property (readonly, copy) NSArray<__kindof NSOperation *> *operations;
@property (readonly) NSUInteger operationCount NS_AVAILABLE(10_6, 4_0);
@property NSInteger maxConcurrentOperationCount;
@end

7.3 存储结构及解构(NSUserDefaults、NSString)


// NSUserDefaults

@interface NSUserDefaults : NSObject
/// -arrayForKey: is equivalent to -objectForKey:, except that it will return nil if the value is not an NSArray.
- (nullable NSArray *)arrayForKey:(NSString *)defaultName;
/// -stringForKey: is equivalent to -objectForKey:, except that it will return nil if the value is not an NSArray<NSString *>. Note that unlike -stringForKey:, NSNumbers are not converted to NSStrings.
- (nullable NSArray<NSString *> *)stringArrayForKey:(NSString *)defaultName;
@end


// NSString

@interface NSString : NSObject <NSCopying, NSMutableCopying, NSSecureCoding>
// Returns an array containing substrings from the receiver that have been divided by a given separator.
- (NSArray<NSString *> *)componentsSeparatedByString:(NSString *)separator;
// Returns an array containing substrings from the receiver that have been divided by characters in a given set.
- (NSArray<NSString *> *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator NS_AVAILABLE(10_5, 2_0);
@end

7.4 容器元素集合(NSHashTable、NSSet、NSDictionary)


// NSHashTable

NS_CLASS_AVAILABLE(10_5, 6_0)
@interface NSHashTable<ObjectType> : NSObject <NSCopying, NSCoding, NSFastEnumeration>
// convenience, return the hash table’s members.
@property (readonly, copy) NSArray<ObjectType> *allObjects;


// NSSet

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

@interface NSSet<ObjectType> (NSExtendedSet)
// return an array containing the set’s members.
@property (readonly, copy) NSArray<ObjectType> *allObjects;
- (NSSet<ObjectType> *)setByAddingObjectsFromArray:(NSArray<ObjectType> *)other NS_AVAILABLE(10_5, 2_0);
@end

@interface NSSet<ObjectType> (NSSetCreation)
// Creates and returns a set containing a uniqued collection of the objects contained in a given array.
//  If the same object appears more than once in array, it is added only once to the returned set.
+ (instancetype)setWithArray:(NSArray<ObjectType> *)array;
- (instancetype)initWithArray:(NSArray<ObjectType> *)array;
@end

@interface NSMutableSet<ObjectType> (NSExtendedMutableSet)
- (void)addObjectsFromArray:(NSArray<ObjectType> *)array;
@end

/****************   Counted Set ****************/
@interface NSCountedSet<ObjectType> : NSMutableSet<ObjectType>
// Returns a counted set object initialized with the contents of a given array.
- (instancetype)initWithArray:(NSArray<ObjectType> *)array;
- (instancetype)initWithSet:(NSSet<ObjectType> *)set;
- (NSUInteger)countForObject:(ObjectType)object;
@end


// NSDictionary

@interface NSDictionary<KeyType, ObjectType> (NSExtendedDictionary)
// return a new array containing the dictionary’s keys, or an empty array if the dictionary has no entries.
// The order of the elements in the array is not defined.
@property (readonly, copy) NSArray<KeyType> *allKeys;
// Returns a new array containing the keys corresponding to all occurrences of a given object in the dictionary.
- (NSArray<KeyType> *)allKeysForObject:(ObjectType)anObject;
// return a new array containing the dictionary’s values, or an empty array if the dictionary has no entries.
// The order of the values in the array isn’t defined.
@property (readonly, copy) NSArray<ObjectType> *allValues;

- (NSArray<ObjectType> *)objectsForKeys:(NSArray<KeyType> *)keys notFoundMarker:(ObjectType)marker;
- (NSArray<KeyType> *)keysSortedByValueUsingSelector:(SEL)comparator;

7.5 应用构件组成(UIScreen、UIApplication)


// UIScreen

NS_CLASS_AVAILABLE_IOS(2_0) @interface UIScreen : NSObject <UITraitEnvironment>
// all screens currently attached to the device
+ (NSArray<UIScreen *> *)screens NS_AVAILABLE_IOS(3_2);
+ (UIScreen *)mainScreen; // the device's internal screen
@end


// UIApplication

NS_CLASS_AVAILABLE_IOS(2_0) @interface UIApplication : UIResponder
@property(nullable, nonatomic,readonly) UIWindow *keyWindow;
// The app’s visible and hidden windows.
@property(nonatomic,readonly) NSArray<__kindof UIWindow *>  *windows;
@end

7.6 视图导航控制堆栈(UIViewController、UINavigationViewController)


// UIViewController

@interface UIViewController (UIContainerViewControllerProtectedMethods)
// An array of children view controllers. This array does not include any presented view controllers.
@property(nonatomic,readonly) NSArray<__kindof UIViewController *> *childViewControllers NS_AVAILABLE_IOS(5_0);
@end


// UINavigationController: stack of UIViewController
// The UINavigationController class implements a specialized view controller that manages the navigation of hierarchical content. 

NS_CLASS_AVAILABLE_IOS(2_0) @interface UINavigationController : UIViewController
// The current view controller stack.
@property(nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers;
// The navigation bar managed by the controller. 
// Pushing, popping or setting navigation items on a managed navigation bar is not supported.
@property(nonatomic,readonly) UINavigationBar *navigationBar;
// For use when presenting an action sheet.
@property(null_resettable,nonatomic,readonly) UIToolbar *toolbar NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED;
@end

@interface UIViewController (UINavigationControllerItem)
// Created on-demand so that a view controller may customize its navigation appearance.
// for UIViewController if navigation needed
@property(nonatomic,readonly,strong) UINavigationItem *navigationItem;
// If YES, then when this view controller is pushed into a controller hierarchy with a bottom bar (like a tab bar), the bottom bar will slide out. Default is NO.
@property(nonatomic) BOOL hidesBottomBarWhenPushed __TVOS_PROHIBITED;
@end

@interface UIViewController (UINavigationControllerContextualToolbarItems)
@property (nullable, nonatomic, strong) NSArray<__kindof UIBarButtonItem *> *toolbarItems NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED;
@end


// UINavigationBar: stack of UINavigationItem
// The UINavigationBar class provides a control for navigating hierarchical content.

NS_CLASS_AVAILABLE_IOS(2_0) @interface UINavigationBar : UIView <NSCoding, UIBarPositioning> 
@property(nullable, nonatomic,readonly,strong) UINavigationItem *topItem; // the top of the navigation bar's stack
@property(nullable, nonatomic,readonly,strong) UINavigationItem *backItem; // immediately below the topmost item on navigation bar's stack
@property(nullable,nonatomic,copy) NSArray<UINavigationItem *> *items;


// UINavigationItem
/*
A UINavigationItem object manages the buttons and views to be displayed in a UINavigationBar object. 
When building a navigation interface, each view controller pushed onto the navigation stack 
must have a UINavigationItem object that contains the buttons and views 
it wants displayed in the navigation bar.
*/

NS_CLASS_AVAILABLE_IOS(2_0) @interface UINavigationItem : NSObject <NSCoding>

- (instancetype)initWithTitle:(NSString *)title NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

// Title when topmost on the stack. default is nil
@property(nullable, nonatomic,copy)   NSString        *title;
// Custom view to use in lieu of a title. May be sized horizontally. 
// Only used when item is topmost on the stack.
@property(nullable, nonatomic,strong) UIView          *titleView; // 可定制标题栏
// Explanatory text to display above the navigation bar buttons.
@property(nullable,nonatomic,copy)   NSString *prompt __TVOS_PROHIBITED;

// Bar button item to use for the back button in the child navigation item.
@property(nullable,nonatomic,strong) UIBarButtonItem *backBarButtonItem __TVOS_PROHIBITED;
// 可定制导航栏左侧按钮项
@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *leftBarButtonItems NS_AVAILABLE_IOS(5_0);
// 可定制导航栏右侧按钮项
@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *rightBarButtonItems NS_AVAILABLE_IOS(5_0); 


// UIToolbar

NS_CLASS_AVAILABLE_IOS(2_0) __TVOS_PROHIBITED @interface UIToolbar : UIView <UIBarPositioning>
// default is UIBarStyleDefault (blue)
@property(nonatomic) UIBarStyle barStyle __TVOS_PROHIBITED;
// get/set visible UIBarButtonItem. default is nil. changes not animated. shown in order
@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *items;


// UITabBarController

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBarController : UIViewController <UITabBarDelegate, NSCoding>
// An array of the root view controllers displayed by the tab bar interface.
@property(nullable, nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers;
// Provided for -[UIActionSheet showFromTabBar:]. 
// Attempting to modify the contents of the tab bar directly will throw an exception.
@property(nonatomic,readonly) UITabBar *tabBar NS_AVAILABLE_IOS(3_0);


// UITabBar

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBar : UIView
// get/set visible UITabBarItems. default is nil.
@property(nullable,nonatomic,copy) NSArray<UITabBarItem *> *items;


// UISplitViewController

NS_CLASS_AVAILABLE_IOS(3_2) @interface UISplitViewController : UIViewController
@property (nonatomic, copy) NSArray<__kindof UIViewController *> *viewControllers;


// UIAlertController

NS_CLASS_AVAILABLE_IOS(8_0) @interface UIAlertController : UIViewController
@property (nonatomic, readonly) NSArray<UIAlertAction *> *actions;
@property (nullable, nonatomic, readonly) NSArray<UITextField *> *textFields;

7.7 视图元素布局层次(UIView、UIControl)


// UIResponder

@interface UIResponder (UIResponderKeyCommands)
@property (nullable,nonatomic,readonly) NSArray<UIKeyCommand *> *keyCommands NS_AVAILABLE_IOS(7_0); // returns an array of UIKeyCommand objects<
@end


// UIView

NS_CLASS_AVAILABLE_IOS(2_0) @interface UIView : UIResponder <NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusEnvironment>

@interface UIView(UIViewHierarchy)
@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *subviews;
@end

@interface UIView (UIViewGestureRecognizers)
@property(nullable, nonatomic,copy) NSArray<__kindof UIGestureRecognizer *> *gestureRecognizers NS_AVAILABLE_IOS(3_2);
@end

@interface UIView (UIViewMotionEffects)
@property (copy, nonatomic) NSArray<__kindof UIMotionEffect *> *motionEffects NS_AVAILABLE_IOS(7_0);
@end

@interface UIView (UIConstraintBasedLayoutInstallingConstraints)
@property(nonatomic,readonly) NSArray<__kindof NSLayoutConstraint *> *constraints NS_AVAILABLE_IOS(6_0);
@end

@interface UIView (UILayoutGuideSupport)
// UILayoutGuide objects owned by the receiver.
@property(nonatomic,readonly,copy) NSArray<__kindof UILayoutGuide *> *layoutGuides NS_AVAILABLE_IOS(9_0);


// UIStackView

NS_CLASS_AVAILABLE_IOS(9_0)
@interface UIStackView : UIView
@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *arrangedSubviews;
@end


// UITableView

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITableView : UIScrollView <NSCoding>
- (nullable NSArray<NSIndexPath *> *)indexPathsForRowsInRect:(CGRect)rect; // returns nil if rect not valid
@property (nonatomic, readonly) NSArray<__kindof UITableViewCell *> *visibleCells;
@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForVisibleRows;
@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForSelectedRows NS_AVAILABLE_IOS(5_0); // returns nil or a set of index paths representing the sections and rows of the selection.
@end


// UIControl

NS_CLASS_AVAILABLE_IOS(2_0) @interface UIControl : UIView
// get info about target & actions. this makes it possible to enumerate all target/actions by checking for each event kind
- (NSSet *)allTargets; // set may include NSNull to indicate at least one nil target
- (UIControlEvents)allControlEvents; // list of all events that have at least one action
- (nullable NSArray<NSString *> *)actionsForTarget:(nullable id)target forControlEvent:(UIControlEvents)controlEvent; // single event. returns NSArray of NSString selector names. returns nil if none


// UISegmentedControl

NS_CLASS_AVAILABLE_IOS(2_0) @interface UISegmentedControl : UIControl <NSCoding>
- (instancetype)initWithItems:(nullable NSArray *)items; // items can be NSStrings or UIImages. control is automatically sized to fit content


参考:

iOS之NSArray方法详解

Objective-C研究院之数组对象(七)

Objective-C语法之NSArray和NSMutableArray

Objective-C数组对象(NSArray和NSMutableArrray)

NSArray排序方法
iOS探索:对NSArray中自定义的对象进行排序

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页