Foundation Kit
Cocoa 是一個(gè)面向?qū)ο蟮能浖M件—---類(lèi)的集成套件逛拱,它使開(kāi)發(fā)者可以快速創(chuàng)建強(qiáng)壯和全功能的 Mac OS X 或者 iOS 應(yīng)用程序溅蛉。
Cocoa包含了很多框架怎茫,其中最最核心的有兩個(gè):
-
Foundation框架
Foundation框架包含所有和界面顯示無(wú)關(guān)的類(lèi)诊杆。
-
Application Kit(AppKit)框架(Cocoa Touch中叫UIKit框架,用于 iOS 開(kāi)發(fā))
Application Kit 框架包含實(shí)現(xiàn)圖形的氓拼、事件驅(qū)動(dòng)的用戶界面需要的所有對(duì)象你画。
Foundation 是兩個(gè) UI 框架的基礎(chǔ),包含很多面向數(shù)據(jù)的簡(jiǎn)單類(lèi)和數(shù)據(jù)類(lèi)型桃漾,它以 CoreFoundation 為基礎(chǔ)坏匪,CoreFoundation 是一個(gè)用純 C 語(yǔ)言寫(xiě)的框架。
一撬统、數(shù)據(jù)類(lèi)型
范圍NSRange
typedef struct _NSRange {
NSUInteger location;
NSUInteger length;
} NSRange;
NSRange 用來(lái)表達(dá)一個(gè)數(shù)據(jù)的范圍适滓,本質(zhì)是一個(gè) C 的結(jié)構(gòu)體,創(chuàng)建方式有三種恋追。
-
直接賦值
NSRange range; range.length = 10; range.location = 12;
-
聚合結(jié)構(gòu)賦值
NSRange range = {10, 12};
-
快捷函數(shù) NSMakeRange()
NSRange range = NSMakeRange(10, 12);
幾何形狀
為了描述幾何形狀而建立的結(jié)構(gòu)體凭迹,包括 CGPoint 和 CGSize 等。
/* Points. */
struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;
/* Sizes. */
struct CGSize {
CGFloat width;
CGFloat height;
};
typedef struct CGSize CGSize;
/* Vectors. */
struct CGVector {
CGFloat dx;
CGFloat dy;
};
typedef struct CGVector CGVector;
/* Rectangles. */
struct CGRect {
CGPoint origin;
CGSize size;
};
typedef struct CGRect CGRect;
這些結(jié)構(gòu)體都在 CoreGraphic 下的 CGGeometry.h 下定義苦囱,同樣的有三種創(chuàng)建方式嗅绸。
CGPoint point = {1, 2};
CGSizeMake(10, 10);
CGRectMake(10, 10, 10, 10);
二、字符串
字符串是一個(gè)經(jīng)常使用的類(lèi)撕彤,在 cocoa 中字符串類(lèi)叫做 NSString鱼鸠。不同于 C 語(yǔ)言中的字符串,NSString 有更多面向?qū)ο蟮奶匦院头椒ā?/p>
創(chuàng)建字符串
NSString * myStr = [NSString stringWithFormat:@"hello %@", @"objectivec"];
允許按照一定格式接受一些參數(shù)去創(chuàng)建一個(gè)字符串羹铅∈凑可以看到源碼中的 stringWithFormat 函數(shù)如下
+ (instancetype)stringWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
省略號(hào)表示它可以接受不定長(zhǎng)參數(shù),stringWithFormat 是一個(gè)工廠方法职员,因?yàn)樗且粋€(gè)可以創(chuàng)建對(duì)象的類(lèi)方法麻蹋。
字符串大小
length 方法返回字符串的長(zhǎng)度,類(lèi)型為 NSUInteger廉邑。
NSString * myStr = [NSString stringWithFormat:@"hello %@", @"objectivec"];
NSLog(@"the length of myStr is %u", [myStr length]);
字符串比較
isEqualToString
isEqualToString 用來(lái)比較兩個(gè)字符串是否相等哥蔚,返回 BOOL 類(lèi)型。
NSString * a = @"abc";
NSString * b = @"abc";
NSString * c = @"ab";
NSLog(@"a : b = %d", [a isEqualToString:b]);
NSLog(@"a : c = %d", [a isEqualToString:c]);
compare
compare 用來(lái)依次比較字符串中的字符蛛蒙,返回一個(gè)枚舉變量
typedef NS_ENUM(NSInteger, NSComparisonResult)
{
NSOrderedAscending = -1L,
NSOrderedSame,
NSOrderedDescending
};
如果字符均相等則返回0糙箍,如果后者首個(gè)不相等字符的值小于前者則返回 -1,否則返回牵祟。
NSString * a = @"bcd";
NSString * b = @"bcd";
NSString * c = @"abc";
NSLog(@"a : b = %d", [a compare:b]);
NSLog(@"a : c = %d", [a compare:c]);
NSLog(@"c : a = %d", [c compare:a]);
當(dāng)然這樣效果還不夠深夯,可以加上 options 參數(shù)來(lái)實(shí)現(xiàn)。
- NSCaseInsensitiveSearch 不區(qū)分大小寫(xiě)
- NSLiteralSearch 區(qū)分大小寫(xiě)
- NSNumericSearch 比較字符個(gè)數(shù)而非字符值
有很多 options 都可以在 NSString.h 中找到诺苹,還可以用 or 運(yùn)算添加多個(gè) option 選項(xiàng)咕晋。
字符串包含
-
前綴檢測(cè)
NSLog(@"%u", [myStr hasPrefix:@"hel"]); //1 NSLog(@"%u", [myStr hasPrefix:@"leh"]); //0
-
后綴檢測(cè)
NSLog(@"%u", [myStr hasSuffix:@"-c"]); //1 NSLog(@"%u", [myStr hasSuffix:@"-d"]); //0
-
區(qū)間檢測(cè)
NSString * myStr = [NSString stringWithFormat:@"hello %@", @"objectivec"]; NSRange range = [myStr rangeOfString:@"ello"]; NSLog(@"location : %u length : %u", range.location, range.length);
返回一個(gè) NSRange 類(lèi)型的值。如果沒(méi)有找到指定字符串收奔,則返回的 NSRange 的 location 為 NSNotFound掌呜,實(shí)測(cè)是一個(gè)很大的數(shù)字。
不變字符串與可變字符串
NSString 是不可變字符串坪哄,意味著不能向里面加入自字符串或者是刪除部分字符串质蕉,要?jiǎng)?chuàng)建可變字符串可以用NSMutableString。NSMutableString 是 NSString 的子類(lèi)翩肌,同時(shí)對(duì) NSString 做了拓展模暗。
創(chuàng)建 NSMutableString 的方法是 NSMutableString 的工廠方法 stringWithCapacity,它需要一個(gè) capacity 參數(shù)作為容量念祭,但是基于動(dòng)態(tài)內(nèi)存的 objectivec 并沒(méi)有限制字符串大小一定是 capacity兑宇。
NSMutableString *target = [NSMutableString stringWithCapacity:50];
[target appendString:@"hello "];
[target appendFormat:@"%@ and you", @"iOS"];
NSLog(@"%@", target);
[target deleteCharactersInRange: [target rangeOfString:@" and you"]];
NSLog(@"%@", target);
添加字符串有 appendString 和 appendFormat 兩種,同時(shí)刪除字符串的 deleteCharactersInRange 方法配合 rangeOfString 方法可以刪除字符串中的指定字符串粱坤。但是注意 deleteCharactersInRange 不會(huì)檢測(cè)范圍合理性隶糕,如果 rangeOfString 傳入的是 NSNotFound 則程序會(huì)報(bào)錯(cuò)。
三站玄、集合
1. 不可變數(shù)組
NSarray 是一個(gè)不可變數(shù)組若厚,一旦創(chuàng)建就不能再添加或刪除。同時(shí) NSArray 限制只能存放 objectivec 的對(duì)象蜒什,不能存儲(chǔ)原始 C 語(yǔ)言的基礎(chǔ)數(shù)據(jù)類(lèi)型测秸,如 int,float灾常,enum霎冯,struct 和 NSArray 中的隨機(jī)指針。NSArray 也不能存放 nil钞瀑,它以 nil 作為結(jié)束符沈撞。
-
通過(guò)類(lèi)方法 arrayWithObjects 創(chuàng)建數(shù)組
NSArray * array = [NSArray arrayWithObjects:@"one", @"two", @"three", nil];
-
通過(guò)數(shù)組字面量創(chuàng)建數(shù)組
NSArray * array1 = @[@"one", @"two", @"three"];
數(shù)組字面量不需要顯式使用 nil 結(jié)束。
-
獲得數(shù)組大小
[array count]
-
通過(guò)對(duì)象方法 objectAtIndex 獲得某個(gè)對(duì)象
[array objectAtIndex:i]
-
通過(guò)數(shù)組下標(biāo)獲得某個(gè)對(duì)象
array1[i]
-
字符串分割為數(shù)組
NSString * target = @"hello you and the world"; NSArray * array = [target componentsSeparatedByString:@" "];
-
數(shù)組以某個(gè)字符為連接符雕什,拼接成字符串
target = [array componentsJoinedByString:@"-"]; NSLog(@"%@", target);
2. 可變數(shù)組
NSMutableArray 是一個(gè)可變數(shù)組缠俺,同樣的它也繼承自 NSArray显晶,支持添加和刪除元素。
-
只能通過(guò)工廠方法創(chuàng)建
NSMutableArray * array = [NSMutableArray arrayWithCapacity:10];
capacity 只具有參考意義壹士。
-
添加元素
[array addObject:@"hello"]; [array addObject:@"you"]; [array addObject:@"and"]; [array addObject:@"the"]; [array addObject:@"world"];
-
按下標(biāo)刪除元素
[array removeObjectAtIndex:2];
-
按元素內(nèi)容刪除元素
[array removeObject:@"you"];
如果元素本身不存在磷雇,不會(huì)報(bào)錯(cuò)。
3. 數(shù)組枚舉方式
對(duì)一個(gè)數(shù)組進(jìn)行枚舉或者遍歷有四種方式
-
通過(guò)索引
for (int i = 0; i < [array count]; i++) { NSLog(@"%@", array[i]); }
-
使用 NSEnumerator
NSEnumerator * enumrator = [array objectEnumerator]; id it = enumrator.nextObject; while (it) { NSLog(@"%@", it); it = enumrator.nextObject; }
還有一個(gè) reverseObjectEnumerator 方法可以獲得反向的枚舉器躏救。
-
使用快速枚舉
快速枚舉是個(gè)新特性唯笙,可以直接通過(guò)一個(gè)元素遍歷數(shù)組。
for (NSString *string in array) { NSLog(@"%@", string); }
-
使用代碼塊方法
[array enumerateObjectsUsingBlock:^(NSString *string, NSUInteger index, BOOL *stop) { NSLog(@"%@", string); }];
代碼塊中 *stop 用于控制循環(huán)是否結(jié)束盒使。
需要注意在枚舉過(guò)程中不能通過(guò)添加或刪除對(duì)象來(lái)改變數(shù)組容量否則會(huì)出現(xiàn)混亂崩掘。使用代碼塊方式的優(yōu)勢(shì)在于可以讓循環(huán)操作并發(fā)執(zhí)行,而快速枚舉則是線性完成的少办。
4. 字典
不可變字典 NSDictionary
字典用于存儲(chǔ) key-value 鍵值對(duì)苞慢。
-
通過(guò)字面量創(chuàng)建字典
NSDictionary *dictionary1 = @{@"one": animal1, @"two": animal2, @"three": animal3, @"four": animal4};
-
通過(guò)類(lèi)方法創(chuàng)建字典,注意順序
NSDictionary *dictionary2 = [NSDictionary dictionaryWithObjectsAndKeys:animal1, @"one", animal2, @"two", animal3, @"three", animal4, @"four", nil];
-
通過(guò)類(lèi)方法創(chuàng)建字典
NSArray *animalArray = [NSArray arrayWithObjects:animal1, animal2, animal3, animal4, nil]; NSArray *keyArray = @[@"one", @"two", @"three", @"four"]; NSDictionary *dictionary3 = [NSDictionary dictionaryWithObjects:animalArray forKeys:keyArray];
-
通過(guò)字面量獲取某個(gè)元素
NSLog(@"%@", dictionary1[@"one"]);
-
通過(guò)對(duì)象方法獲取某個(gè)元素
NSLog(@"%@", [dictionary1 objectForKey:@"one"]);
可變字典 NSMutableDictionanry
可變字典允許對(duì)字典插入或刪除元素英妓。
-
通過(guò)類(lèi)方法創(chuàng)建可變字典
NSMutableDictionary *dictionary1 = [NSMutableDictionary dictionary];
-
通過(guò)類(lèi)方法創(chuàng)建可變字典
NSMutableDictionary *dictionary2 = [NSMutableDictionary dictionaryWithCapacity:10];
-
添加元素
[dictionary1 setObject:animal1 forKey:@"one"];
如果字典中已經(jīng)有了該元素則會(huì)覆蓋枉疼。
-
刪除元素
[dictionary1 removeObjectForKey: @"three"];
刪除不存在的元素不會(huì)報(bào)錯(cuò)。
-
遍歷字典
-
for 循環(huán)
NSArray *keys = [dictionary1 allKeys]; for (int i = 0; i < [keys count]; i++) { NSLog(@"%@", dictionary1[keys[i]]); }
-
快速枚舉
for (NSString *key in dictionary1) { NSLog(@"%@", dictionary1[key]); }
-
代碼塊接口
[dictionary1 enumerateKeysAndObjectsUsingBlock:^(NSString *key, Animal *value, BOOL *stop) { NSLog(@"%@", value); }];
-
四鞋拟、其他數(shù)值
1. NSNumber
objectivec 不支持自動(dòng)裝箱開(kāi)箱骂维,所以需要手動(dòng)對(duì)基本數(shù)據(jù)類(lèi)型進(jìn)行封裝。
-
通過(guò)類(lèi)方法封裝
NSNumber *age; age = [NSNumber numberWithInteger:20]; NSLog(@"%@", age); age = [NSNumber numberWithFloat:20.0]; NSLog(@"%@", age); age = [NSNumber numberWithDouble:20.0]; NSLog(@"%@", age); age = [NSNumber numberWithChar: 'U' - 'A']; NSLog(@"%@", age); age = [NSNumber numberWithBool:YES];
-
通過(guò)字面量語(yǔ)法封裝
NSNumber *age; age = @20; NSLog(@"%@", age); age = @20.0f; NSLog(@"%@", age); age = @'X'; NSLog(@"%@", age); age = @YES; NSLog(@"%@", age);
-
開(kāi)箱操作
NSLog(@"%c", [age charValue]); NSLog(@"%d", age.intValue);
2. NSValue
NSValue 是 NSNumber 的父類(lèi)贺纲,它可以封裝包括結(jié)構(gòu)體在內(nèi)的任意值航闺。
-
創(chuàng)建NSValue
NSMutableArray *reacts = [NSMutableArray arrayWithCapacity:10]; NSRect rect = NSMakeRect(10, 20, 5, 5); NSValue *value = [NSValue valueWithBytes:&rect objCType:@encode(NSRect)];
這里 valueWIthBytes 是一個(gè)類(lèi)方法,接受需要封裝的結(jié)構(gòu)體的地址猴誊,@encode 將數(shù)據(jù)類(lèi)型轉(zhuǎn)換為描述這個(gè)數(shù)據(jù)類(lèi)型的字符串潦刃。
-
獲取值
[reacts addObject:value]; [[reacts objectAtIndex:0] getValue:&rect];
通過(guò) getValue 獲得的值,根據(jù)傳入的指針地址存儲(chǔ)在所指向的變量地址內(nèi)懈叹。
3. NSNull
為了表達(dá)類(lèi)似 null 的含義乖杠,可以使用 NSNull 類(lèi),它只有一個(gè) null 方法澄成,用以創(chuàng)建一個(gè) null 值胧洒。
NSNull *null = [NSNull null];