關於 iOS 集合官方文檔的一份小筆記

添加到 iOS 集合內的對象必須是對象。
做爲集合,須要知足三個基本的特性:獲取元素查找元素遍歷元素
若是集合是可變的還須要另外支持 添加元素刪除元素html

Array

添加到 Array 內的元素都是有序的,同一對象可屢次被添加到集合。和其它集合相比,Array 遍歷內部元素十分方便。數組

Array 內元素必須是對象 (NSPointArray 除外)。bash

Array 的分類

  • NSArray 初始化後元素就不可再增刪。app

  • NSMuatbleArray 初始化後能夠隨時添加或刪除元素對象。ide

  • NSPointArrayNSMuatbleArray 類似,區別是能夠指定對元素的強/弱引用。也就是說 NSPointArray 內部元素爲對象 或 nil性能

關於數組的一些知識點:

  1. indexOfObjectindexOfObjectIdenticalTo 的區別?

兩個方法都是來判斷某一對象是不是 Array 集合內元素,若是是則返回該對象在集合內的索引。兩個方法的區別就在於兩個 API 斷定的依據:indexOfObject 會使用 isEqualTo 方法將 Object 與集合元素進行比較。而 indexOfObjectIdenticalTo 則會比較 Object 與集合元素的指針是否相同。ui

  1. 關於數組排序,單一條件的值比較排序使用 SortedArrayUsingComparatorSortedArrayUsingSelector 很容易,若是給你兩個甚至多個排序條件呢?好比對學生分數排序,排序條件爲,優先按總分降序排列,總分相同再比較數學成績降序排列,數學成績也相同比較語文成績降序排列··· ··· 前面的兩個排序方法固然也能知足咱們的需求,可是如今要討論的是另外一種更優雅的實現:使用 NSSortDescriptor
Student *p1 = [[Student alloc] initWithName:@"zhonger" id:@"1" score:552 math:130 chinese:90 english:120];
    Student *p2 = [[Student alloc] initWithName:@"zhonger" id:@"1" score:552 math:130 chinese:90 english:120];
    Student *p3 = [[Student alloc] initWithName:@"zhonger" id:@"1" score:552 math:130 chinese:90 english:120];
    Student *p4 = [[Student alloc] initWithName:@"zhonger" id:@"1" score:552 math:130 chinese:90 english:120];
    Student *p5 = [[Student alloc] initWithName:@"zhonger" id:@"1" score:552 math:130 chinese:90 english:120];

    NSArray *students = @[p1, p2, p3, p4, p5];

    NSSortDescriptor *des1 = [[NSSortDescriptor alloc]initWithKey:@"score" ascending:NO];
    NSSortDescriptor *des2 = [[NSSortDescriptor alloc] initWithKey:@"math" ascending:NO];
    NSSortDescriptor *des3 = [[NSSortDescriptor alloc] initWithKey:@"chinese" ascending:NO];

    NSArray *newArray1 = [students sortedArrayUsingDescriptors:@[des1,des2,des3]];
    NSLog(@"%@",newArray1);
複製代碼

是否是比以前的排序方法可讀性提高了不少,並且代碼後期也更好維護。this

Dictionary

Dictionary 內部元素以 key:value 鍵值對的形式存在,添加到 Dictionary 內的鍵值對是無序的,而且具備同一 key 值的鍵值對對象重複添加會相互覆蓋。當某個鍵值對添加到 Dictionary 時,Dictionary 會對 key 進行深拷貝,而對 value 進行淺拷貝,已經添加到集合內部的鍵值對,key 值將不可更改。而 value 值爲強引用,當 value 爲可變對象時,修改 value 對象,字典內的 value 也會被修改。spa

key 爲任何遵循 NSCopying 協議並實現了 hashisEqual 方法的對象。
value 爲任何對象(包括集合)翻譯

key 須要很好地實現哈希方法,不然字典的設值、查找、獲取、增長等操做耗時將線性增長。通常咱們都用 NSString 做爲 key 值,是由於 NSString 很好地實現了哈希方法。這些操做的耗時爲常量。

字典能夠根據 value 值對 key 進行排序,排序後獲得的是一個 key 數組。

Dictionary 的分類

  • NSDictionary 初始化後就不可再增刪鍵值對。
  • NSMutableDictionary 初始化後能夠隨時添加或刪除鍵值對。
  • NSMapTable 相似 NSMutableDictionary 能夠指定對 value 的強/弱引用。也就是說 NSMapTable 內部元素的 value 值能夠爲 nil

關於字典的一些知識點:

咱們在使用 Dictionnary 時,通常將 String 做爲 key 值 ,從而能夠知足絕大部分需求。但有時也會遇到使用自定義對象做爲 key 的狀況。那麼做爲 key 的對象都須要知足哪些條件呢?

  1. key 必須遵循 NSCopying 協議,由於當元素漸入字典後,會對 key 進行深拷貝。
  2. key 必須實現 hashisEqual 方法。(便於快速獲取元素並保證 key 的惟一性)。

並不建議使用特別大的對象做爲 key,可能會致使性能問題。

Set

添加到 Set 內的元素都是無序的,同一對象只能被添加一次。和其它集合相比,Set 查找內部元素十分快速。

set 集合元素要很好地實現 hash 方法(時間複雜度爲O(1)),不然時間複雜度爲 O(k)

Set 的分類

  • NSSet 初始化後就不可再增刪元素。
  • NSMuatbleSet 初始化後可隨時增刪元素。
  • NSCountedSet 每一個元素都帶有一個計數,添加元素,計數爲一。重複添加某個元素則計數加一;移除元素計數減一,計數爲零則移除
  • NSHashTableNSMutableSet 相似,區別是可指定對元素的強/弱引用,內部元素能夠爲 nil

Index set

IndexSet 保存的 Array 子集,存儲元素爲 Arrayindex 索引,存儲形式爲索引範圍。 eg: (0,3,4)->(NSRange(0,1),NSRange(3,2))

Index set 的分類

  • NSIndexSet 初始化後就不可再增刪元素。
  • NSMutableIndexSet 初始化後可隨時增刪元素。

使用場景通常爲記錄數組的某些元素,好比列表多選行,可使用 NSIndexSet 來記錄選擇了哪行,而不是另外建立一個可變數組

Index path

保存嵌套數組的某個元素 path
如(0,2,0)

  • **NSIndexPath **

使用場景通常是 TableViewdataSource 代理方法。

嚴格意義上說,indexPath 並非集合。其只是記錄嵌套數組內某子元素的路徑位置。此處聽從官方文檔將 indexPath 和集合一塊兒討論。

深拷貝與淺拷貝

如下爲官方定義,考慮到翻譯後理解可能會出現誤差,筆者並未進行翻譯,牆裂建議讀者本身閱讀加深理解。

Shallow Copies

There are a number of ways to make a shallow copy of a collection. When you create a shallow copy, the objects in the original collection are sent a retain message and the pointers are copied to the new collection. Listing 1 shows some of the ways to create a new collection using a shallow copy.

Listing 1 Making a shallow copy

NSArray *shallowCopyArray = [someArray copyWithZone:nil];
NSDictionary *shallowCopyDict = [[NSDictionary alloc] initWithDictionary:someDictionary copyItems:NO];
複製代碼

These techniques are not restricted to the collections shown. For example, you can copy a set with the copyWithZone: method—or the mutableCopyWithZone: method—or an array with initWithArray:copyItems: method.

Deep Copies

There are two ways to make deep copies of a collection. You can use the collection’s equivalent of initWithArray:copyItems: with YES as the second parameter. If you create a deep copy of a collection in this way, each object in the collection is sent a copyWithZone: message. If the objects in the collection have adopted the NSCopying protocol, the objects are deeply copied to the new collection, which is then the sole owner of the copied objects. If the objects do not adopt the NSCopying protocol, attempting to copy them in such a way results in a runtime error. However, copyWithZone: produces a shallow copy. This kind of copy is only capable of producing a one-level-deep copy. If you only need a one-level-deep copy, you can explicitly call for one as in Listing 2.

Listing 2 Making a deep copy

This technique applies to the other collections as well. Use the collection’s equivalent of initWithArray:copyItems: with YES as the second parameter.

If you need a true deep copy, such as when you have an array of arrays, you can archive and then unarchive the collection, provided the contents all conform to the NSCodingprotocol. An example of this technique is shown in Listing 3.

Listing 3 A true deep copy

NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:oldArray]];  

複製代碼

參考

官方文檔連接

相關文章
相關標籤/搜索