OC學習Runtime之協議與分類

2021-09-30 13:14:58 字數 4564 閱讀 4757

堅持 成長 每日一篇

oc提供分類為已有的類進行擴充套件,提供協議來定義介面。

分類:允許我們通過給乙個類新增方法來擴充它(但是通過category不能新增新的例項變數),並且我們不需要訪問類中的**就可以做到。分類在oc的定義為category

category是表示乙個指向分類的結構體objc_category的指標,其定義如下:

typedef

struct objc_category *category;

objc_category結構體定義如下

struct objc_category
這個結構體主要包含了分類定義的例項方法與類方法,其中instance_methods列表是objc_class中方法列表的乙個子集,而class_methods列表是元類方法列表的乙個子集。

protocol的定義如下:

#ifdef __objc__

@class

protocol;

#else

typedef

struct objc_object protocol;

#endif

struct objc_object ;
我們可以看到,protocol其實就是乙個物件結構體。

runtime並沒有在系統中找到提供針對分類的操作函式。因為這些分類中的資訊都包含在objc_class中,我們可以通過針對objc_class的操作函式來獲取分類的資訊。下面我們可以做一些測試。。。。

準備乙個boy類和boy類的分類test如下:

boy.h

#import 

@inte***ce

boy : nsobject

-(void)say:(nsstring*)str girl:(nsstring*)girl;

@end

boy.m

#import "boy.h"

#import "girl.h"

@implementation

boy-(void)say:(nsstring*)str girl:(nsstring*)girl

@end

boy+test.h

#import "boy.h"

@inte***ce

boy (test)

-(void)run;

@end

boy+test.m

#import "boy+test.h"

@implementation

boy (test)

-(void)run

@end

例項:

unsigned int outcount= 0;

method *methodlist = class_copymethodlist

(boy.class, &outcount);

for (int i = 0; i < outcount; i++)

}

輸出:

2015-09-23

11:21:25.491 runtime[10007:631112] boy's method: say:girl:

2015-09-23 11:21:29.215 runtime[10007:631112] boy's method: run

2015-09-23

11:21:47.598 runtime[10007:631112] 分類方法run在objc_class的方法列表中

當新增分類時候新增的方法是新增到類裡面。雖然系統沒有提供動態新增分類,但是我們可以給類新增方法是乙個效果的。。

而對於protocol,runtime提供了一系列函式來對其進行操作,這些函式包括:

// 返回指定的協議

protocol * objc_getprotocol ( const

char *name );

// 獲取執行時所知道的所有協議的陣列

protocol ** objc_copyprotocollist ( unsigned int

*outcount );

// 建立新的協議例項

protocol * objc_allocateprotocol ( const

char *name );

// 在執行時中註冊新建立的協議

void objc_registerprotocol ( protocol *proto );
// 為協議新增方法

void protocol_addmethoddescription ( protocol *proto, sel name, const

char *types, bool isrequiredmethod, bool isinstancemethod );

// 新增乙個已註冊的協議到協議中

void protocol_addprotocol ( protocol *proto, protocol *addition );
// 為協議新增屬性

void protocol_addproperty ( protocol *proto, const

char *name, const objc_property_attribute_t *attributes, unsigned

int attributecount, bool isrequiredproperty, bool isinstanceproperty );

// 返回協議名

const

char * protocol_getname ( protocol *p );

// 測試兩個協議是否相等

bool protocol_isequal ( protocol *proto, protocol *other );
// 獲取協議中指定條件的方法的方法描述陣列

struct objc_method_description * protocol_copymethoddescriptionlist ( protocol *p, bool isrequiredmethod, bool isinstancemethod, unsigned

int *outcount );

// 獲取協議中指定方法的方法描述

struct objc_method_description protocol_getmethoddescription ( protocol *p, sel asel, bool isrequiredmethod, bool isinstancemethod );
// 獲取協議中的屬性列表

objc_property_t * protocol_copypropertylist ( protocol *proto, unsigned int

*outcount );

// 獲取協議的指定屬性

objc_property_t protocol_getproperty ( protocol *proto, const

char *name, bool isrequiredproperty, bool isinstanceproperty );

// 獲取協議採用的協議

protocol ** protocol_copyprotocollist ( protocol *proto, unsigned int

*outcount );

// 檢視協議是否採用了另乙個協議

bool protocol_conformstoprotocol ( protocol *proto, protocol *other );

objc_getprotocol函式,需要注意的是如果僅僅是宣告了乙個協議,而未在任何類中實現這個協議,則該函式返回的是nil。

● objc_copyprotocollist函式,獲取到的陣列需要使用free來釋放

● objc_allocateprotocol函式,如果同名的協議已經存在,則返回nil

● objc_registerprotocol函式,建立乙個新的協議後,必須呼叫該函式以在執行時中註冊新的協議。協議註冊後便可以使用,但不能再做修改,即註冊完後不能再向協議新增方法或協議

需要強調的是,協議一旦註冊後就不可再修改,即無法再通過呼叫protocol_addmethoddescription、protocol_addprotocol和protocol_addproperty往協議中新增方法等。

小結 runtime並沒有提供過多的函式來處理分類。對於協議,我們可以動態地建立協議,並向其新增方法、屬性及繼承的協議,並在執行時動態地獲取這些資訊。

Runtime 五 協議與分類

objectvie c中的分類允許我們通過乙個類新增方法來擴充它 但是通過category不能新增新的例項變數 並且我們不需要訪問類中的 就可以做到。objectvie c中的協議是普遍存在的介面定義方式,即在乙個類中通過 protocol定義介面,在另外類中實現介面,這種介面定義方式也成為 del...

OC之block 和協議

一 bolck 一 簡介 block是什麼?蘋果推薦的型別,效率高,在執行中儲存 用來封裝和儲存 有點像函式,block可以在任何時候執行。bolck和函式的相似性 1 可以儲存 2 有返回值 3 有形參 4 呼叫方式一樣。識別符號 二 基本使用 1 定義block變數 int sumblock i...

oc學習之旅 簡單協議

import import boss.h import coder.h int main int argc,const char argv 4.方 方遵守協議 協議 實現介面 5.使用 時 必須設定 a.delegate b boss b boss alloc init autorelease co...