深入淺出Objective-C筆記(九)

Foundation Framework(2)


集合類

用來存儲和管理一組對象的類

  • 三種常用的集合類

NSArray:強調順序,但是里面的元素可以相同

NSDictionary:鍵值對的形式,鍵不講究順序

NSSet:不強調順序,元素是互不相同的

三種集合類的示意圖.png
創建NSArray對象

方法一:

NSArray *array = [NSArray arrayWithObjects:@"str1", @"str2", @"str3", nil];
//調用了NSArray的工廠方法
//用nill標記序列的結束

方法二:

NSArray *array = [[NSArray alloc] initWithObjects:@"str1", @"str2", @"str3", nil];

方法三:
就像NSString創建字符串對象很常見一樣,創建數組也太常用了,所以,OC為創建數組提供了一種簡單的語法:

NSArray *array = @[@"str1", @"str2", @"str3"];

數組里的nil是結束標志,如果在中間出現nil,就會被認為這是末尾。但如果我們確實想在中間元素中有個空值,那這么辦?

NSNull *null = [NSNull null];
//使用NSNull類(單例類)創建一個 null對象

//注意null 與nil的區別,null是有對象的,只是這個對象是空的,它只是用來占位的。而nil是真的沒有一個對象。

注意:NSArray只能存儲對象!

基本數據類型,比如C語言里的int,float,double, 結構體等,以及Foundation Framework里的NSInteger 都不能存儲在NSArray里,因為它們都不是對象。

但如果確實想存儲這些類型,怎么辦?

Foundation Framework 提供了基本數據類型的包裝對象。也就是說我們可以把這些基本數據類型包裝在一個對象里面,這樣就可以把這些數據作為對象來處理了。


包裝類
  • NSNumber

NSNumber 提供的把基本數據類型轉換為對象的方法

NSNumber *intNum = [NSNumber numberWithInt:20];
NSNumber *doubleNum = [NSNumber numberWithDouble:20.5];
NSNumber *floatNum = [NSNumber numberWithFloat:98.98787f];
NSNumber *boolNum = [NSNumber numberWithBool:YES];

//使用NSNumber類方法,把基本數據類型當作參數傳進去,這個方法就會返回一個NSNumber對象

如何把NSNumber對象里的數值取出來用?

int a = [intNum intValue];
double b = [doubleNum doubleValue];
float c = [floatNum floatValue];
BOOL d = [boolNum boolValue];

//每個對象都有特定的方法,可以返回特定類型的數據

每次要創建NSNumber對象的時候,都要調用NSNumber的類方法,很麻煩,有沒有方便的辦法?

ObjC2.0后,提供了更方便的字面量的寫法。

NSNumber *intNum = @20;
NSNumber *doubleNum = @20.5;
NSNumber *floatNum = @98.98787f;
NSNumber *boolNum = @YES;

NSNumber可以對C語言的基本數據類型進行封裝(成為對象),但是對于更復雜的,比如結構體,字節序列等,就得用另外一種方式進行封裝,用NSNumber的父類,NSValue來處理。

  • NSValue

如何把一個結構體包裝進NSValue并生產一個NSValue對象?

  typedef struct {
      int a;
      float b;
  }DataType;
  //這是個結構體,是無法包裝進一個NSNumber里的

  使用NSValue來包裝結構體

  DataType data;//定義一個結構體變量
  NSValue *value = [NSValue valueWithBytes:&data objCType:@encode(Data Type)];

  //調用NSValue的類方法,傳入data的指針,
  //第二個參數是data的數據類型(這個例子data的數據類型是結構體)
  //如此這般便創建出一個NSValue對象

  //注意`encode`是OC的關鍵字,可以得到數據類型的C的字符串表示。
  //也就是說,`@encode(DataType)`返回的是`DataType`這么一個字符串

如何把包裝在NSValue對象(Value)里的數據取出來?

[value getValue:&data];
//傳入data變量的地址,getValue方法就會把包裝起來的數據重新寫回到我們傳入的這個地址里,
//然后就可以直接使用里面的數據了。

現在我們有了NSNumber 和NSValue,我們就可以把各種數據類型寫進NSArray數組里了。


讀取NSArray某個下標位置的對象
  - (id)objectAtIndex:(NSUInteger)index;

一個例子

NSArray *arrayOfString = @[@"str1", @"str2", @"str3", @"str4"];
NSString *str = [arrayOfString objectAtIndex:2];//返回第三個字符串的指針
//這個方法還是麻煩

更簡潔的寫法

NSString *str = arrayOfString[2];//跟C語言數組用法一樣

另一個常用的集合類,NSDictionary

在字典里我們可以很方便的根據一個鍵來找到對應的數值。

對于字典的鍵,需要注意兩點:

字典的鍵,必須是不可變對象
字典的鍵,必須兩兩不相同

  • 如何創建一個字典
  NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
                          @64, @"intValue";
                          @19.8, @"doubleValue";
                          @YES, @"boolValue", nil];
  //調用NSDictionary的一個工廠方法dictionaryWithObjectsAndKeys:

  //注意先寫值對象,再寫鍵對象

  //最后的nil也是用來判斷傳入參數序列的結束
  • 字面量的創建方式
  NSDictionary *dict = @{@"intValue":@64,
                       @"double":@19.8,
                       @"boolValue":@YES};
   //鍵寫在前面,后面是值
  • 如何根據字典的鍵查找對應的值?

第一種方式
- (id)objectForKey:(id)aKey;

e.g.

NSObject *obj = [dict objectForKey:@"intValue"];

精簡版

NSObject *obj = dict[@"intValue"];
//看著有點像數組的用法,只是數組下標變成了字典鍵

集合類NSSet

NSSet使用頻率較低,當使用它是一般是考慮到效率問題。
當我們要判斷一個集合里是不是有一個對象的時候,一個方法是使用NSArray數組掃一遍。而使用NSSet不需要遍歷,效率高了很多。

  • 如何創建一個NSSet對象?
  NSSet *set = [NSSet setWithObjects:@"A", @"B", @"C", @"D", nil];

  //跟NSArray類似,這也是運用類里的工廠方法來生成對象
  • 如何判斷一個集合里是否包含某個對象?
  BOOL isContained = [set containsObject:@"A"];

  //如果包含,則返回YES,否則返回NO.

因為NSSet使用頻率不高,所以OC沒提高更簡便的方法

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容