上一章咱們學習了OC內存管理的相關知識,瞭解了OC程序在運行中對象及變量是如何釋放以達到不佔用內存的效果。本章咱們來學習OC的block,protocol協議和Foundation框架。程序員
第一講 block設計模式
1. block簡介數組
block封裝了一段代碼,能夠在任什麼時候候執行多線程
block能夠做爲函數參數或者函數的返回值,而其自己又能夠帶輸入參數或返回值。app
蘋果官方建議儘可能多用block。在多線程、異步任務、集合遍歷、集合排序、動畫轉場用的不少框架
2. block的定義異步
block的標誌:^,block是用來保存一段代碼函數
block跟函數很像:學習
1.能夠保存代碼動畫
2.有返回值
3.有形參
4.調用方式同樣
1> 如何定義block變量
int (^sumBlock)(int, int); // 帶參數
void (^myBlock)(); // 不帶參數
2> 如何利用block封裝代碼
^(int a, int b) { // 帶參數a和b
return a - b;
};
^() { // 不帶參數
NSLog(@"----------");
};
^ { // 不帶參數而且省略小括號()
NSLog(@"----------");
};
3. block訪問外面變量
* block內部能夠訪問外面的變量
* 默認狀況下,block內部不能修改外面的局部變量
* 給局部變量加上__block關鍵字,這個局部變量就能夠在block內部修改
4. 利用typedef定義block類型
typedef int (^MyBlock)(int, int);
// 之後就能夠利用MyBlock這種類型來定義block變量
MyBlock block;
MyBlock b1, b2;
b1 = ^(int a, int b) {
return a - b;
};
MyBlock b3 = ^(int a, int b) {
return a - b;
};
下面咱們經過代碼來學習一下block跟局部變量之間的關係:
1 void test() 2 { 3 int a = 10; 4 __block int b = 20; 5
6 void (^block)(); 7
8 block = ^{ 9 // block內部能夠訪問外面的變量 10 //NSLog(@"a = %d", a); 11
12 // 默認狀況下,block內部不能修改外面的局部變量 13 // a = 20; 14
15 // 給局部變量加上__block關鍵字,這個局部變量就能夠在block內部修改
16 b = 25; 17 }; 18 block(); 19 }
第二講 protocol協議
1、 protocol協議
1. 協議的基本用途
*能夠用來聲明一大堆方法(不能聲明成員變量)
*只要某個類遵照了這個協議,就至關於擁有這個協議中的全部方法聲明
*只要父類遵照了某個協議,就至關於子類也遵照了
2. 協議的定義
@protocol 協議名稱 <NSObject> //遵照基協議
// 方法聲明列表....
@end
3. 如何遵照協議
1> 類遵照協議
*只要某個類遵照了協議,就擁有了這個協議中得全部方法聲明,父類遵照,子類徹底遵照。
@interface 類名 : 父類名 <協議名稱1, 協議名稱2>
@end
2> 協議遵照協議
*一個協議能夠遵照其餘多個協議,多個協議之間用逗號 , 隔開
*一個協議遵照了其餘協議,就至關於擁有了其餘協議中的方法聲明
@protocol 協議名稱 <其餘協議名稱1, 其餘協議名稱2>
@end
4. 協議中方法聲明的關鍵字
協議中有2個關鍵字能夠控制方法是否要實現(默認是@required),在大多數狀況下,用途在於程序員之間的交流
1> @required (默認)
要求實現,若是沒有實現,會發出警告
2> @optional
不要求實現,怎樣不會有警告
5. 定義一個變量的時候,限制這個變量保存的對象遵照某個協議
類名<協議名稱> *變量名;
id<協議名稱> 變量名;
NSObject<MyProtocol> *obj;
id<MyProtocol> obj2;
若是沒有遵照對應的協議,編譯器會警告
6. @property中聲明的屬性也可用作一個遵照協議的限制
@property (nonatomic, strong) 類名<協議名稱> *屬性名;
@property (nonatomic, strong) id<協議名稱> 屬性名;
@property (nonatomic, strong) Dog<MyProtocol> *dog;
@property (nonatomic, strong) id<MyProtocol> dog2;
7. 協議可用定義在單獨.h文件中,也可用定義在某個類中
1> 若是這個協議只用在某個類中,應該把協議定義在該類中
2> 若是這個協議用在不少類中,就應該定義在單獨文件中
8. 分類可用定義在單獨.h和.m文件中,也可用定義在原來類中
1> 通常狀況下,都是定義在單獨文件
2> 定義在原來類中的分類,只要求能看懂語法
9. 基協議
*NSObject是一個基類,最根本最基本的類,任何其餘類最終都要繼承它
*其實還有一個協議,名字也叫NSObject,它是一個基協議,最根本最基本的協議
*NSObject協議中聲明不少最基本的方法,好比description、retain、release等
*建議每一個新的協議都要遵照NSObject協議
2、 代理設計模式
1. 設計原理
有些麻煩的事情不想本身親自作,就能夠找我的幫忙作,即交給代理對象去作
2. 設計原則
*首先得擁有某個代理對象屬性
*其次要很清楚代理有哪些方法
*最後要保證能解耦
3. 實現方案
*定義一個protocol,在其中聲明一些和代理溝通的方法
*擁有一個代理屬性id<protocol> delegate
*讓代理遵照protocol
第三講 Foundation框架
Foundation框架中包含了不少開發經常使用的數據類型,結構體、枚舉等。下面列舉出經常使用的結構體。
1、 Foundation框架-結構體
1. NSRange(location length)表示範圍
建立變量的三種方式
NSRange r1 = {1,2}; // 可讀性差
NSRange r2 = {.location = 1,length = 2}; // 代碼冗長
NSRange r3 = NSMakeRange(1,2); // Foundation自帶函數,經常使用
查找字符串的範圍
NSString *str = @」jack andy」;
NSRange r = [str rangeOfString:@」rose」];
// 找不到,location=NSNotFound=-1;length=0.
2. NSPoint/CGPoint表示座標
NSPoint p1 = CGPointMake(1,2)//經常使用
CGPoint p2 = NSMakePoint(1,2)
3. NSSize/CGSize表示UI元素的的尺寸(寬度,高度)
NSSize s1 = CGSizeMake(100, 50);
NSSize s2 = NSMakeSize(100, 50);
CGSize s3 = NSMakeSize(200, 60);
4. NSRect/CGrect(CGPoint CGsize)UI元素的位置和尺寸
CGRect r1 = CGRectMake(0, 0, 100, 50);
CGRect r2 = { {0, 0}, {100, 90}};
CGRect r3 = {p1, s2};
CGPointZero == CGPointMake(0,0);//原點
// 利用框架中函數將結構體轉爲字符串
NSString *str = NSStringFromPoint(p1);
2、 Foundation框架-字符串
1. NSString:不可變字符串
(1)建立字符串的六種形式
*NSString *s1 = @"jack";
*NSString *s2 = [[NSString alloc] initWithString:@"jack"];
*NSString *s3 = [[NSString alloc] initWithFormat:@"age is %d", 10];
// C字符串 --> OC字符串
*NSString *s4 = [[NSString alloc] initWithUTF8String:"jack"];
// OC字符串 --> C字符串
*const char *cs = [s4 UTF8String];
*NSUTF8StringEncoding 用到中文就能夠用這種編碼
NSString *s5 =[[NSString alloc] initWithComtentsOfFile:@」文件路徑」 encoding:NSUTF8StringEncoding error:nil];
// URL : 資源路徑
// 協議頭:// 路徑
// file://
// ftp://
NSURL *url = [[NSURL alloc] initWithString:@」file://文件路徑」]
NSURL *url = [NSURL fileURLWithPath:@」文件路徑」];
NSString *s6 = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
[NSURL URLWithString:(NSString *)]; // 通常都會有個類方法跟對象方法配對,類方法一般以類名開頭
(2)字符串的導入導出
// 字符串的導出
[@」haha」 writeToFile:@」文件路徑」 atomically:YES NSUTF8StringEncoding error:nil];
NSString *str = @」haha123」;
NSURL *url = [NSURL fileURLWithPath:@」文件路徑」];
[str writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:nil];
2. NSMutableString:可變字符串
NSMutableString *s1 = [NSMutableString stringWithFormat:@"Hello my Kitty "];
// 拼接內容到s1的後面
[s1 appendString:@" ohoh"];
// 獲取my的範圍
// 一個獲取範圍,一個進行刪除
NSRange range = [s1 rangeOfString:@"my"];
[s1 deleteCharactersInRange:range];//刪除my以後的字符串
// 不可變字符串實現拼接成新的字符串
NSString *s2 = [NSString stringWithFormat:@"Hello Kitty"];
// s2的內容拷貝一份,加上字符串返回新的字符串
NSString *s3 = [s2 stringByAppendingString:@" oh my god"];
3、 Foundation框架-集合
1. NSArray和NSMutableArray
1>NSArray是OC中使用的數組,只能存放OC對象,不能存放非OC對象類型,如int、struct、enum等等
建立OC數組:
NSArray *array1 = [NSArray arrayWithObject:@」jack」];//單個元素
// 多個元素,結尾必須以nil結尾
NSArray *array2 = [NSArray arrayWithObjects:@」jack」,@」andy」,nil];
// 快速建立一個OC數組
NSArray *array3 = @[@」jack」,@」andy」];
// 訪問OC數組元素和C語言同樣
array2[0] ;
// 獲取數組元素的個數
array.count;
2>NSArray的遍歷
1 #import "Person.h"
2
3 int main() 4 { 5 Person *p = [[Person alloc] init]; 6
7 NSArray *array = @[p, @"jack", @"andy"]; 8
9 // for循環快速遍歷數組元素 10 // id obj表明着數組中的每個元素
11 for (id obj in array) 12 { 13 // 快速找出obj元素在數組中的位置
14 NSUInteger i = [array indexOfObject:obj]; 15
16 NSLog(@"%ld - %@", i, obj); 17 } 18 // 使用block遍歷 19 // 每遍歷一個元素,就會調用一次block,並把當前元素的索引位置看成參數傳給block
20 [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){ 21 NSLog(@"%ld - %@", idx, obj); 22
23 if (idx == 0) 24 { 25 // 中止遍歷
26 *stop = YES; 27 } 28 }]; 29 return 0; 30 }
3>NSMutableArray
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"haha", @"andy", nil];
// 添加元素
[array addObject:@"Kitty"];
// 刪除元素
[array removeAllObjects];
// 刪除指定的對象
[array removeObject:@"haha"];
// 刪除指定索引的元素
[array removeObjectAtIndex:1];
// 錯誤寫法
[array addObject:nil];
// @[]只能建立不可變數組NSArray
NSMutableArray *array = @[@」andy」];// 錯
2. NSSet和NSMutableSet
1>NSSet
NSSet *s = [NSSet set];
// 建立多元素NSSet
NSSet *s1 =[NSSet setWithObjects:@」jack」,@」andy」,nil];
// 隨機取出一個元素
NSString *s2 = [s1 anyObject];
2>NSMutableSet
NSMutableSet *s = [NSMutableSet set];
// 添加元素
[s addObject:@」haha」];
// 刪除指定元素
[s removeObject:(id)];
3>NSSet和NSArray
都是集合,都能存放多個對象
都只能存放OC對象
自己不可變,都有一個可變的子類
不一樣:NSSet無序,NSArray有序
3. NSDictionary和NSM
根據key找到value。裏面存儲的東西都是鍵值對。
1>NSDictionaryutableDictionary
// 建立字典
NSDictionary *dict = [NSDictionary dictionaryWithObject:@」jack」 forKey:@」name」];
// 快速建立字典
NSDictionary *dict = @{@」name」:@」jack」};
// 訪問
// 根據key獲取對應的值
id obj = [dict objectForKey:@」name」];
// 快速訪問
id obj = dict [@」name」];
// 添加、移除鍵值對
[dict setObject:@」jack」 forKey:@」name」];
[dict removeObjectForKey:(id)];
2>遍歷
NSDictionary的遍歷和上面提到的NSArray的遍歷是同樣的,能夠經過for循環和block遍歷,下面我只寫一下block遍歷。
[dict enumerateKeysAndObjectsUsingBlock:
^(id key, id obj, BOOL *stop) {
NSLog(@"%@ - %@", key, obj);
// *stop = YES;
}];
注意:字典不容許有相同的key,但容許有相同的value,字典也是無序的。
3>NSMutableDictionary
建立、訪問等和父類同樣,惟一要注意的地方是下面這個:
//返回的是NSDictionary類型的
NSMutableDictionary *dict = @{@"name" : @"jack"};
[dict setObject:@"rose" forKey:@"name"];
4、 NSNumber、NSDate、NSValue
1. NSNumber
將基本數據類型包裝成對象
NSNumber *num = [NSNumber numberWithInt:25];
NSDictionary *dict =@{@」age」: num};
NSNumber *num1 = dict[@」age」];
int a = [num2 intValue];
編譯器特性:自動將基本數據類型包裝成對象
NSArray *aray = @{@」age」:@20};
@’A’ ;//NSNumber對象 @(age)
@」A」;//NSString對象
2. NSValue
NSNumber繼承自NSValue。
// 結構體--->OC對象
CGPoint p = CGPointMake(10, 10);
// 將結構體轉爲Value對象
NSValue *value = [NSValue valueWithPoint:p];
// 將value轉爲對應的結構體
// [value pointValue];
NSArray *array = @[value ];
3. NSDate
// 建立一個時間對象
NSDate *date = [NSDate date];
// 打印出的時候是0時區的時間(北京-東8區)
NSLog(@"%@", date);
NSDate *date2 = [NSDate dateWithTimeInterval:5 sinceDate:date];
// 從1970開始走過的秒數
NSTimeInterval seconds = [date2 timeIntervalSince1970];
// [date2 timeIntervalSinceNow];
//日期格式化
NSString *time = @"2015/4/10 23:11";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//y年M月d日 24時m分
formatter.dateFormat = @"yyyy/MM/dd HH:mm";
NSDate *date = [formatter dateFromString:time];
本章學習總結:
本章的主要學習了block,protocol協議和Foundation框架,其中重點是Foundation框架。須要咱們平時多加練習,慢慢領會,由於Foundation是咱們從此開發中很是重要的框架,必須咱們熟練的掌握。
本章主要分爲三講內容,第一講主要學習了block,要掌握定義block變量,和利用block封裝代碼,熟練掌握block的基本定義規範以及使用。第二講咱們主要學習了protocol協議,要掌握協議的定義和如何遵照協議,協議方法聲明的兩個關鍵字要知道怎麼使用。第三講主要學習了Foundation框架,也是本章最重要的內容,總結告終構體、字符串、集合等不一樣的Foundation框架的使用,可能知識有點多,但須要多鞏固練習,爭取熟記下這些框架的內容。