處理 Foundation

2018-08-12 21:55 更新

處理 Foundation

開始編寫應(yīng)用程序的代碼時(shí),可以利用大量的 Objective-C 框架。其中,為所有應(yīng)用程序提供基本服務(wù)的 Foundation 框架尤為重要。Foundation 框架包括表示基本數(shù)據(jù)類型的值類(如字符串和數(shù)字)以及用于儲(chǔ)存其他對(duì)象的集 (collection) 類。ToDoList 應(yīng)用程序中的大量代碼都可以依靠值類和集類來編寫。

值對(duì)象

Foundation 框架提供了為字符串、二進(jìn)制數(shù)據(jù)、日期與時(shí)間、數(shù)字以及其他值產(chǎn)生值對(duì)象的類。

值對(duì)象是指封裝了基本值(屬于 C 數(shù)據(jù)類型)且提供與該值相關(guān)的服務(wù)的對(duì)象。您會(huì)頻繁遇到值對(duì)象,作為應(yīng)用程序調(diào)用的方法和函數(shù)的參數(shù)和返回值??蚣艿牟煌糠?,甚至不同的框架都可以通過傳遞值對(duì)象來交換數(shù)據(jù)。

以下是 Foundation 框架中值對(duì)象的幾個(gè)示例:

NSString 和 NSMutableString
NSData 和 NSMutableData
NSDate
NSNumber
NSValue

由于值對(duì)象表示標(biāo)量值,因此您可以在集 (collection) 中使用,也可以在任何需要對(duì)象的地方使用?;谥祵?duì)象所封裝的基本類型,它們有一項(xiàng)天然優(yōu)勢(shì):可讓您采用簡(jiǎn)單而高效的方式對(duì)封裝的值執(zhí)行某些操作。例如,NSString 類具有用于搜索和替換子字符串、將字符串寫入文件或(首選)URL 以及構(gòu)建文件系統(tǒng)路徑的方法。

您可以從基本類型的數(shù)據(jù)創(chuàng)建值對(duì)象(然后在方法參數(shù)中傳遞它)。稍后,您可通過代碼從該對(duì)象訪問被封裝的數(shù)據(jù)。NSNumber 類是這一方法最清晰的示例。

int n = 5; // Value assigned to primitive type
NSNumber *numberObject = [NSNumber numberWithInt:n]; // Value object created from primitive type
int y = [numberObject intValue]; // Encapsulated value obtained from value object (y == n)

大多數(shù)值類會(huì)通過聲明初始化程序和類工廠方法來創(chuàng)建其實(shí)例。類工廠方法由類實(shí)施,作為提供給客戶的簡(jiǎn)單方法;它將分配和初始化結(jié)合為一個(gè)步驟,并返回已創(chuàng)建的對(duì)象。例如,NSString 類可聲明 string 類方法,以便分配和初始化類的新實(shí)例,并將其返回到代碼中。

NSString *string = [NSString string];

除創(chuàng)建值對(duì)象和讓您訪問其封裝值之外,大多數(shù)值類都提供用于簡(jiǎn)單操作(如對(duì)象比較)的方法

字符串

Objective-C 指定字符串的約定與 C 相同:?jiǎn)蝹€(gè)字符會(huì)使用單引號(hào)括起來,而字符串則使用雙引號(hào)括起來。但是,Objective-C 框架通常不使用 C 字符串。相反,它們會(huì)使用 NSString 對(duì)象。

NSString 類為字符串提供了一個(gè)對(duì)象包裝器,它具有諸多優(yōu)勢(shì),如內(nèi)置了可用于儲(chǔ)存任意長(zhǎng)度字符串的內(nèi)存管理、提供了對(duì)各種字符編碼(特別是 Unicode)的支持,以及用于格式化字符串的實(shí)用工具等。因?yàn)槟ǔ?huì)使用此類字符串,所以 Objective-C 提供了速寫記法,即根據(jù)常量值來創(chuàng)建 NSString 對(duì)象。要使用此 NSString 字面常量,只需在雙引號(hào)字符串前面添加 (@) 符號(hào),如下例所示:

// Create the string "My String" plus carriage return.
NSString *myString = @"My String\n";
// Create the formatted string "1 String".
NSString *anotherString = [NSString stringWithFormat:@"%d %@", 1, @"String"];
// Create an Objective-C string from a C string.
NSString *fromCString = [NSString stringWithCString:"A C string" encoding:NSUTF8StringEncoding];

數(shù)字

Objective-C 提供了創(chuàng)建 NSNumber 對(duì)象的速寫記法,從而無需調(diào)用初始化程序或類工廠方法就可以創(chuàng)建此類對(duì)象。只需在數(shù)值前面添加 (@) 符號(hào),并選擇一個(gè)添加在其后面的值類型指示。例如,創(chuàng)建封裝整數(shù)值和雙精度值的 NSNumber 對(duì)象,可以編寫如下代碼:

NSNumber *myIntValue    = @32;
NSNumber *myDoubleValue = @3.22346432;

您甚至可以使用 NSNumber 字面常量來創(chuàng)建封裝的 Boolean 值和字符值。

NSNumber *myBoolValue = @YES;
NSNumber *myCharValue = @'V';

可以創(chuàng)建 NSNumber 對(duì)象,表示無符號(hào)整型 (unsigned integers)、長(zhǎng)整型 (long integers)、長(zhǎng)長(zhǎng)整型 (long long integers) 和浮點(diǎn)值 (float values),方法是將字符“U”、“L”、“LL”和“F”分別追加到記號(hào)值末尾。例如,創(chuàng)建封裝浮點(diǎn)值的 NSNumber 對(duì)象,可以編寫如下代碼:

NSNumber *myFloatValue = @3.2F

集對(duì)象

Objective-C 代碼中的大多數(shù)集對(duì)象都是一種基礎(chǔ)集類(NSArray、NSSet 和 NSDictionary)的實(shí)例。這些類用于管理對(duì)象組,因此要添加到集 (collection) 中的任何項(xiàng)目都必須是 Objective-C 類的實(shí)例。如果要添加標(biāo)量值,就必須先創(chuàng)建合適的 NSNumber 或 NSValue 實(shí)例來表示它。

添加進(jìn)集的任何對(duì)象的生命周期都將不短于集。因?yàn)榧悤?huì)使用強(qiáng)引用來跟蹤其內(nèi)容。除了跟蹤其內(nèi)容之外,每個(gè)集類都便于您執(zhí)行特定的任務(wù),如枚舉、訪問特定項(xiàng)目或是找出特殊的對(duì)象是否屬于集的一部分。

NSArray、NSSet 和 NSDictionary 類的內(nèi)容在創(chuàng)建時(shí)就應(yīng)設(shè)定。因?yàn)樗鼈儾荒茈S時(shí)間而變化,所以被稱為不可變。每個(gè)類還有一個(gè)可變的子類,允許您隨意添加或移除對(duì)象。不同類型的集采用不同的方式組織它們所包含的對(duì)象:

  • NSArray 和 NSMutableArray—數(shù)組,包含有序的對(duì)象集。通過在數(shù)組中指定對(duì)象的位置(即索引)來訪問對(duì)象。數(shù)組中首個(gè)元素的索引是 0(零)。
  • NSSet 和 NSMutableSet—集合,儲(chǔ)存無序的對(duì)象集,其中每個(gè)對(duì)象僅出現(xiàn)一次。一般是將測(cè)試或過濾器應(yīng)用到集合中的對(duì)象,來訪問這些集合中的對(duì)象。
  • NSDictionary 和 NSMutableDictionary—字典,其條目?jī)?chǔ)存為鍵-值對(duì);鍵是唯一的標(biāo)識(shí)符,通常為字符串,而值則是您要儲(chǔ)存的對(duì)象。通過指定鍵,您可以訪問該對(duì)象。

數(shù)組

數(shù)組 (NSArray) 用于表示有序的對(duì)象列表。只要求每個(gè)項(xiàng)目都是 Objective-C 對(duì)象;不要求每個(gè)對(duì)象都是同一個(gè)類的實(shí)例。

如果要保持?jǐn)?shù)組中的順序,每個(gè)元素都應(yīng)儲(chǔ)存在從 0 開始的索引中。

創(chuàng)建數(shù)組

與本章前文所述的值類一樣,您可以通過分配和初始化、類工廠方法或數(shù)組字面常量來創(chuàng)建數(shù)組。

根據(jù)對(duì)象數(shù)量的不同,可用的初始化和工廠方法也多種多樣。

+ (id)arrayWithObject:(id)anObject;
+ (id)arrayWithObjects:(id)firstObject, ...;
- (id)initWithObjects:(id)firstObject, ...;

由于 arrayWithObjects: 和 initWithObjects: 方法都采用了以 nil 結(jié)束且數(shù)量可變的參數(shù),所以您必須包括 nil 并將其作為最后一個(gè)值。

NSArray *someArray =
[NSArray arrayWithObjects:someObject, someString, someNumber, someValue, nil];

此示例會(huì)創(chuàng)建一個(gè)如上文所示的數(shù)組。第一個(gè)對(duì)象 someObject 的數(shù)組索引為 0;最后一個(gè)對(duì)象 someValue 的索引則為 3。

如果所提供的其中一個(gè)值為 nil ,則有可能使項(xiàng)目列表意外截?cái)唷?/p>

id firstObject = @"someString";
id secondObject = nil;
id thirdObject = @"anotherString";
NSArray *someArray =
  [NSArray arrayWithObjects:firstObject, secondObject, thirdObject, nil];

在這種情況下,someArray 只會(huì)包含 firstObject,因?yàn)?secondObject(即 nil)會(huì)被解析為項(xiàng)目列表的末尾。

使用緊湊語(yǔ)法創(chuàng)建數(shù)組字面常量也是有可能的。

NSArray *someArray = @[firstObject, secondObject, thirdObject];

使用此語(yǔ)法時(shí),請(qǐng)勿使用 nil 來結(jié)束對(duì)象列表;實(shí)際上,nil 是無效值。例如,如果您嘗試執(zhí)行以下代碼,那么會(huì)在運(yùn)行時(shí)中捕獲到一個(gè)異常:

id firstObject = @"someString";
id secondObject = nil;
NSArray *someArray = @[firstObject, secondObject];
// exception: "attempt to insert nil object"

查詢數(shù)組對(duì)象

創(chuàng)建數(shù)組后,可以通過查詢來獲得信息,如其中有多少個(gè)對(duì)象,或者其中是否包含給定的項(xiàng)目。

NSUInteger numberOfItems = [someArray count];

if ([someArray containsObject:someString]) {
    ...
}

還可以按照給定索引查詢數(shù)組來找到項(xiàng)目。如果請(qǐng)求的索引無效,那么會(huì)在運(yùn)行時(shí)中獲得越界異常。為了避免得到異常,應(yīng)始終首先檢查項(xiàng)目的數(shù)量。

if ([someArray count] > 0) {
    NSLog(@"First item is: %@", [someArray objectAtIndex:0]);
}

此示例用于檢查項(xiàng)目的數(shù)量是否大于 0。如果數(shù)量大于 0,F(xiàn)oundation 函數(shù) NSLog 會(huì)記錄第一個(gè)項(xiàng)目(索引為 0)的描述。

除了使用 objectAtIndex: 之外,還可以使用下標(biāo)語(yǔ)法來查詢數(shù)組,就像在標(biāo)準(zhǔn)的 C 數(shù)組中訪問值一樣。上一個(gè)示例可被重寫為:

if ([someArray count] > 0) {
    NSLog(@"First item is: %@", someArray[0]);
}

排序數(shù)組對(duì)象

NSArray 類提供了多種方法對(duì)其收集的對(duì)象進(jìn)行排序。由于 NSArray 是不可變的,因此這類方法都會(huì)返回新的數(shù)組,并在其中包含排好序的項(xiàng)目。

例如,您可以通過在每個(gè)字符串上調(diào)用 compare:,對(duì)字符串?dāng)?shù)組進(jìn)行排序。

NSArray *unsortedStrings = @[@"gammaString", @"alphaString", @"betaString"];
NSArray *sortedStrings =
         [unsortedStrings sortedArrayUsingSelector:@selector(compare:)];

可變性

雖然 NSArray 類本身不可變,但它仍可包含可變對(duì)象。例如,如果將可變字符串添加到不可變的數(shù)組,如下所示:

NSMutableString *mutableString = [NSMutableString stringWithString:@"Hello"];
NSArray *immutableArray = @[mutableString];

就可讓您變異該字符串。

if ([immutableArray count] > 0) {
    id string = immutableArray[0];
    if ([string isKindOfClass:[NSMutableString class]]) {
        [string appendString:@" World!"];
    }
}

如果要在初始創(chuàng)建數(shù)組后添加或移除對(duì)象,可使用 NSMutableArray,它提供了很多方法來添加、移除或替換一個(gè)或多個(gè)對(duì)象。

NSMutableArray *mutableArray = [NSMutableArray array];
[mutableArray addObject:@"gamma"];
[mutableArray addObject:@"alpha"];
[mutableArray addObject:@"beta"];

[mutableArray replaceObjectAtIndex:0 withObject:@"epsilon"];

此示例創(chuàng)建了由對(duì)象 @"epsilon"、@"alpha" 和 @"beta" 構(gòu)成的數(shù)組。

還可以對(duì)可變數(shù)組進(jìn)行適當(dāng)排序,而無需創(chuàng)建二級(jí)數(shù)組。

[mutableArray sortUsingSelector:@selector(caseInsensitiveCompare:)];

在這種情況下,包含在內(nèi)的項(xiàng)目會(huì)按升序且不區(qū)分大小寫的順序排列(@"alpha"、@"beta" 和 @"epsilon")。

集合

集合 (NSSet) 對(duì)象與數(shù)組類似,只是其中包含的是各種無序的對(duì)象。

因?yàn)榧喜话樞?,所以測(cè)試成員資格時(shí),集合比數(shù)組更快。

由于基礎(chǔ) NSSet 類是不可變的,因此在創(chuàng)建時(shí)就必須指定其內(nèi)容,其中可使用分配和初始化或者類工廠方法。

NSSet *simpleSet =
  [NSSet setWithObjects:@"Hello, World!", @42, aValue, anObject, nil];

如同 NSArray,initWithObjects: 和 setWithObjects: 方法都采用了以 nil 結(jié)束且數(shù)量不固定的參數(shù)??勺兊?NSSet 子類名稱是 NSMutableSet。

即使您多次嘗試添加對(duì)象,集合也只會(huì)儲(chǔ)存對(duì)單個(gè)對(duì)象的一次引用。

    NSNumber *number = @42;
    NSSet *numberSet =
      [NSSet setWithObjects:number, number, number, number, nil];
    // numberSet only contains one object

字典

與簡(jiǎn)單匯集有序或無序的對(duì)象集不同,字典 (NSDictionary) 會(huì)儲(chǔ)存與給定鍵相關(guān)的對(duì)象,用于以后的檢索。

最佳實(shí)踐是將字符串對(duì)象用作字典鍵。

雖然其他對(duì)象也可以用作鍵,但要注意,每個(gè)鍵都會(huì)被拷貝以供字典使用,并且必須支持 NSCopying。不過,如果要使用鍵-值編碼,則必須為字典對(duì)象使用字符串鍵。若要了解更多信息,請(qǐng)參閱《Key-Value Coding Programming Guide》(鍵值編碼編程指南)。

創(chuàng)建字典

您可以使用分配、初始化,或者類工廠方法來創(chuàng)建字典,如下所示:

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
               someObject, @"anObject",
         @"Hello, World!", @"helloString",
                      @42, @"magicNumber",
                someValue, @"aValue",
                      nil];

對(duì)于 dictionaryWithObjectsAndKeys: 和 initWithObjectsAndKeys: 方法,每個(gè)對(duì)象都會(huì)在其鍵前進(jìn)行聲明,并且對(duì)象列表和鍵必須以 nil 結(jié)束。

Objective-C 提供了一種簡(jiǎn)潔的語(yǔ)法來創(chuàng)建字典字面常量。

NSDictionary *dictionary = @{
              @"anObject" : someObject,
           @"helloString" : @"Hello, World!",
           @"magicNumber" : @42,
                @"aValue" : someValue
};

對(duì)于字典字面常量,鍵會(huì)在其對(duì)象前被指定,并且對(duì)象列表和鍵不以 nil 結(jié)束。

查詢字典

創(chuàng)建字典后,您可以查詢儲(chǔ)存在給定鍵中的對(duì)象。

NSNumber *storedNumber = [dictionary objectForKey:@"magicNumber"];

如果找不到該對(duì)象,objectForKey: 方法會(huì)返回 nil。

同樣也可以用下標(biāo)語(yǔ)法來替代 objectForKey:。

NSNumber *storedNumber = dictionary[@"magicNumber"];

可變性

創(chuàng)建字典后,如果需要添加或移除對(duì)象,可使用 NSMutableDictionary 子類。

[dictionary setObject:@"another string" forKey:@"secondString"];
[dictionary removeObjectForKey:@"anObject"];

使用 NSNull 表示 nil

因?yàn)樵?Objective-C 中,nil 表示“無對(duì)象”。因此不可能將 nil 添加到此節(jié)所描述的集類中。如果要在集 (collection) 中表示“無對(duì)象”,應(yīng)使用 NSNull 類。

NSArray *array = @[ @"string", @42, [NSNull null] ];

使用 NSNull,null 方法始終都會(huì)返回相同的實(shí)例。按此方式工作的類稱為單例類。您可以按如下所示的方法來檢查數(shù)組中的對(duì)象是否等于已共享的 NSNull 實(shí)例:

for (id object in array) {
    if (object == [NSNull null]) {
        NSLog(@"Found a null object");
    }
}

雖然 Foundation 框架包含的功能比文中所述要豐富的多,但也不需要您立即了解每一處細(xì)節(jié)。如果確實(shí)想更深入學(xué)習(xí) Foundation,可以參閱《Foundation Framework Reference》(Foundation 框架參考)?,F(xiàn)在,您已經(jīng)掌握了足夠的信息來繼續(xù)完成 ToDoList 應(yīng)用程序了,那么就從編寫自定數(shù)據(jù)類開始吧。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)