【OC基礎】02-分類(Category)、協議(Protocol)、代碼塊(Block)

分類(Category)

(1)、分類的基礎知識編程

分類是在不改變原有類內容的基礎上,爲類增長一些方法的方式。閉包

(2)、分類的注意事項框架

1>分類只能增長方法,不能增長成員變量;編程語言

2>在分類方法的實現中能夠訪問原來類中的成員變量;函數

3>分類中能夠從新實現原來類中的方法,可是這樣會致使原來的方法沒法在使用ui

4>在大規模應用中。一般把相應的功能寫成分類,對原有的類進行擴充,通常分模塊寫,一個模塊一個分類this

分類的實現

咱們能夠再上一節Student類的基礎上增長分類:atom

CateStudent.h方法聲明:spa

1 #import <Foundation/Foundation.h>
2 #import "Student.h"
3 @interface Student (CatStudent)
4 - (void)eat;
5 - (void)study;
6 @end

CateStudent.m方法實現:code

 1 #import "CateStudent.h"
 2 @implementation Student (CatStudent)
 3 
 4 - (void)eat {
 5     NSLog(@"add eat,age=%i...",age);
 6 }
 7 
 8 - (void)study {
 9     NSLog(@"add study...");
10 }
11 
12 @end

main.m的實現:

 1 #import <Foundation/Foundation.h>
 2 #import "CateStudent.h"
 3 int main(int argc, const char * argv[])
 4 {
 5 
 6     @autoreleasepool {
 7         
 8         // insert code here...
 9         Student *stu = [[Student alloc]init];
10         [stu eat];
11         [stu study];
12         [stu release];
13     }
14     return 0;
15 }

協議(Protocol)

(1)、協議介紹

在ObjC中使用@protocol定義一組方法規範,實現此協議的類必須實現對應的方法。這就像面向對象編程語言中的接口同樣,由於OC中Interface已經用於定義類了,因此定義接口用了一個新的關鍵字Protocol。

(2)、協議的注意事項

1>一個協議能夠擴展自另外一個協議,若是須要擴展多個協議中間使用逗號分隔;

2>和其餘高級語言中接口不一樣的是協議中定義的方法不必定是必須實現的,咱們能夠經過關鍵字進行@required和@optional進行設置,若是不設置則默認是@required(注意ObjC是弱語法,即便不實現必選方法編譯運行也不會報錯);

3>協議經過<>進行實現,一個類能夠同時實現多個協議,中間經過逗號分隔;

4>協議的實現只能在類的聲明上,不能放到類的實現上(也就是說必須寫成@interface Person:NSObject<AnimalDelegate>而不能寫成@implementation Person<AnimalDelegate>);

5>協議中不能定義屬性、成員變量等,只能定義方法;

3、協議的實現

協議的聲明PersonDelegate.h文件:

 1 #import <Foundation/Foundation.h>
 2 
 3 @protocol PersonDelegate <NSObject>
 4  @required
 5 - (void) eat;
 6 
 7 @optional
 8 
 9 - (void)run;
10 - (void)say;
11 @end

Student.h文件:

1 #import <Foundation/Foundation.h>
2 #import "PersonDelegate.h"
3 @interface Student : NSObject<PersonDelegate>
4 
5 - (void) eat;
6 - (void) study;
7 
8 @end

Student.m文件:

 1 #import "Student.h"
 2 
 3 @implementation Student
 4 - (void) eat {
 5     NSLog(@"eat...");
 6 }
 7 - (void) study {
 8     NSLog(@"study...");
 9 }
10 @end

 代碼塊(Block)

在不少語言中的事件機制都是經過回調函數來實現的,由於框架不能提早知道在發生某個事件的時候用戶如何處理這個事件,因此在框架要提供一個能讓用戶註冊本身的事件處理函數的功能。在ObjC中也有相似的方法,稱之爲代碼塊(Block)。Block就是一個函數體(匿名函數),它是OC對於閉包的實現,在塊狀中咱們能夠持有或引用局部變量,同時利用Block也能夠將一個函數做爲一個參數進行傳遞。

MyButton.h

1 #import <Foundation/Foundation.h>
2 @class MyButton;
3 typedef void(^clickEvent)(MyButton*);
4 
5 @interface MyButton : NSObject
6 
7 @property(nonatomic,copy)clickEvent click;
8 -(void)onClick;
9 @end

MyButton.m

 1 #import "MyButton.h"
 2 
 3 @implementation MyButton
 4 
 5 -(void)onClick{
 6     NSLog(@"on click it...");
 7     if(self.click){
 8         _click(self);
 9     }
10 }
11 @end

main.m

 1 #import <Foundation/Foundation.h>
 2 #import "MyButton.h"
 3 int main(int argc, const char * argv[])
 4 {
 5 
 6     @autoreleasepool {
 7         MyButton *btn=[[MyButton alloc]init];
 8         btn.click=^(MyButton *b){
 9             NSLog(@"this is click event...");
10         };
11         [btn onClick];
12     }
13     return 0;
14 }

關於Block須要注意一下幾點:

  1. Block類型定義:返回值類型(^ 變量名)(參數列表)
  2. Block的實現:^(參數列表){操做主體}
  3. Block中能夠讀取塊外面定義的變量可是不能修改,若是要修改那麼這個變量必須聲明_block修飾;
相關文章
相關標籤/搜索