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 头文件已将数组元素声明为支持
协议的类型,数组作为参数则声明为 NSArray 。
Cocoa 的 NSArray 是基于 C 底层 CFArray/CFArrayRef 实现的,NSArray 可以看做是一个 CFArrayRef 的 Wrapper类。
__NSArrayI(Immutable)是NSArray的真正类型(_internal),__NSArrayM(Mutable)是NSMutableArray的真正类型(_internal)。
@interface NSArray<__covariant ObjectType> : NSObject
@interface NSMutableArray : NSArray C 原生数据类型(Native Data Type: int,char,double,etc)不能直接作为 NSArray 元素,它们必须通过装箱(boxing)成 NSNumber、NSString 或 NSValue 等 OC 对象才能纳入 OC 数组存储。
在苹果 WWDC2012 大会上介绍了大量 Objective-C 的新特性,其中有一点就是Objective-C Literals(参考1、2、3),它允许你在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 之 Clang、LLVM 与 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。
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
*)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 *)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
*)array; // initWithArray: 以下是比较常用的类方法便利构造方法:
+ (instancetype)arrayWithObjects:(ObjectType)firstObj, ...NS_REQUIRES_NIL_TERMINATION; // initWithObjects:count:
+ (instancetype)arrayWithArray:(NSArray
*)array; // initWithArray:
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
*)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]; // operator [] 下标写法 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
(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.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
*)otherArray; 示例:
id fo = [array firstObjectCommonWithArray:subArray]; NSLog(@"fo= %@", fo); // e1
4.1 subArray
以下代码获取数组前一半子数组:// 返回指定范围(起始索引、长度)的子数组 // Returns a new array containing the receiving array’s elements that fall within the limits specified by a given range. - (NSArray
*)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
*) arrayByAddingObject:(id)anObject; - (NSArray *) arrayByAddingObjectsFromArray:(NSArray *)otherArray;
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
*)otherArray; 5.3 insertObject
//在指定索引处插入一个元素,原来的元素后移 // index取值范围=[0, count],index=count时相当于addObject - (void)insertObject:(ObjectType)anObject atIndex:(NSUInteger)index; //在指定索引集合处插入一个数组元素,相当于批次insertObject: atIndex: - (void)insertObjects:(NSArray
*)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
*)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 *)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
*)otherArray; // 对照 removeObjectsAtIndexes - (void)removeAllObjects; // Empties the array of all its elements.
NSMutableArray 的 addObject 会对纳入管理的 obj 发送retain 消息。
NSMutableArray 的 removeObject 会对 obj 发送release 消息(解除引用关系)。
NSMutableArray 的 release 或removeAllObjects 会对所有元素发送release 消息。
6.1 Using Selector(-[NSArray(NSExtendedArray) sortedArrayUsingSelector:])
针对 NSDictionary 或自定义的数据模型 FileModel 可自定义实现 compare: 方法,然后将其作为分类 SEL( comparator ) 。
以下按照文件列表( NSMutableArray < FileModel *>* fileList )的时间戳进行降序排列,从近到远展示文件:@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
// 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 方法直接对数组进行排序。
相对于 SEL 和 Descriptor,该方法直接将数组内部的元素排好序,而非返回 copy,使用时可根据需要选择。// 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); }
最后,本节简要梳理 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
*)allBundles; // Returns an array of all of the application’s bundles that represent frameworks. + (NSArray *)allFrameworks; @end //////////////////////////////////////////////////////////////////////////////// // NSThread //////////////////////////////////////////////////////////////////////////////// @interface NSThread : NSObject // Returns an array containing the call stack return addresses. + (NSArray *)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 *)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
*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 *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
. Note that unlike -stringForKey:, NSNumbers are not converted to NSStrings. - (nullable NSArray *)stringArrayForKey:(NSString *)defaultName; @end //////////////////////////////////////////////////////////////////////////////// // NSString //////////////////////////////////////////////////////////////////////////////// @interface NSString : NSObject // Returns an array containing substrings from the receiver that have been divided by a given separator. - (NSArray *)componentsSeparatedByString:(NSString *)separator; // Returns an array containing substrings from the receiver that have been divided by characters in a given set. - (NSArray *)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
: NSObject // convenience, return the hash table’s members. @property (readonly, copy) NSArray *allObjects; //////////////////////////////////////////////////////////////////////////////// // NSSet //////////////////////////////////////////////////////////////////////////////// @interface NSSet<__covariant ObjectType> : NSObject @interface NSSet (NSExtendedSet) // return an array containing the set’s members. @property (readonly, copy) NSArray *allObjects; - (NSSet *)setByAddingObjectsFromArray:(NSArray *)other NS_AVAILABLE(10_5, 2_0); @end @interface NSSet (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 *)array; - (instancetype)initWithArray:(NSArray *)array; @end @interface NSMutableSet (NSExtendedMutableSet) - (void)addObjectsFromArray:(NSArray *)array; @end /**************** Counted Set ****************/ @interface NSCountedSet : NSMutableSet // Returns a counted set object initialized with the contents of a given array. - (instancetype)initWithArray:(NSArray *)array; - (instancetype)initWithSet:(NSSet *)set; - (NSUInteger)countForObject:(ObjectType)object; @end //////////////////////////////////////////////////////////////////////////////// // NSDictionary //////////////////////////////////////////////////////////////////////////////// @interface NSDictionary (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 *allKeys; // Returns a new array containing the keys corresponding to all occurrences of a given object in the dictionary. - (NSArray *)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 *allValues; - (NSArray *)objectsForKeys:(NSArray *)keys notFoundMarker:(ObjectType)marker; - (NSArray *)keysSortedByValueUsingSelector:(SEL)comparator; 7.5 应用构件组成(UIScreen、UIApplication)
//////////////////////////////////////////////////////////////////////////////// // UIScreen //////////////////////////////////////////////////////////////////////////////// NS_CLASS_AVAILABLE_IOS(2_0) @interface UIScreen : NSObject
// all screens currently attached to the device + (NSArray *)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
@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 *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 - (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 *leftBarButtonItems NS_AVAILABLE_IOS(5_0); // 可定制导航栏右侧按钮项 @property(nullable,nonatomic,copy) NSArray *rightBarButtonItems NS_AVAILABLE_IOS(5_0); //////////////////////////////////////////////////////////////////////////////// // UIToolbar //////////////////////////////////////////////////////////////////////////////// NS_CLASS_AVAILABLE_IOS(2_0) __TVOS_PROHIBITED @interface UIToolbar : UIView // 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 *items; //////////////////////////////////////////////////////////////////////////////// // UITabBarController //////////////////////////////////////////////////////////////////////////////// NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBarController : UIViewController // 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 *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 *actions; @property (nullable, nonatomic, readonly) NSArray *textFields; 7.7 视图元素布局层次(UIView、UIControl)
//////////////////////////////////////////////////////////////////////////////// // UIResponder //////////////////////////////////////////////////////////////////////////////// @interface UIResponder (UIResponderKeyCommands) @property (nullable,nonatomic,readonly) NSArray
*keyCommands NS_AVAILABLE_IOS(7_0); // returns an array of UIKeyCommand objects< @end //////////////////////////////////////////////////////////////////////////////// // UIView //////////////////////////////////////////////////////////////////////////////// NS_CLASS_AVAILABLE_IOS(2_0) @interface UIView : UIResponder @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 - (nullable NSArray *)indexPathsForRowsInRect:(CGRect)rect; // returns nil if rect not valid @property (nonatomic, readonly) NSArray<__kindof UITableViewCell *> *visibleCells; @property (nonatomic, readonly, nullable) NSArray *indexPathsForVisibleRows; @property (nonatomic, readonly, nullable) NSArray *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 *)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 - (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中自定义的对象进行排序》