block、protocol和Foundation

 

  上一章咱們學習了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框架的使用,可能知識有點多,但須要多鞏固練習,爭取熟記下這些框架的內容。

相關文章
相關標籤/搜索