天天看點

objective-c中的協定和類别

            Objective-c語言的的面向對象的繼承特性秉承了但繼承的特性,這樣避免的多重繼承下會出現的缺陷,可是同樣會有單繼承的不足。在java方面,是通過接口的方式提供解決,類可以通過實作接口中的方法來解決實際的問題。而Objective-c中采用的是協定的方式,雖然叫法不同,但是其實質是類似的。不過是不同變成語言的差異化。

          不同于java中的接口關鍵字Interface,objective-c中是@protocol,在java的接口中,是允許使用成員變量的,成員變量的預設修飾符是 publi static final。而Objective-c中不允許成員變量。其格式一般入下

@protocol NetworkClient
@required
-(void) networkConnector:(NetworkConnector *) inNetConnector;
@optional
-(void) networkConnectorDisconnected:(NetworkConnector *) inNetConnector;
@end
           

@required 表示此方法是必須實作的

@optional 表示的方法是可實作、可不實作的

對于非必須實作的方法,在實作協定的類的對象執行個體中如果需要調用這些方法,必須先要判斷是否實作了這些方法,如果沒用實作,而調用的話,程式就會崩潰。

判斷方法respondsToSelector,是執行個體方法也是類方法,用于判斷某個類/執行個體是否能處理某個方法(包括基類方法)。

[obj respondsToSelector:@selector(方法名)]

@selector指令意思是将一個方法簽名轉化成Slector對象

當然還可以判斷一個對象是否實作了某個協定,其方法是conformsToprotocol

[obj conformsToprotocol:@protocol(協定名)]

而java中接口中的方法必須全部實作

當一個類需要實作此協定應該如何實作那,java中通過關關鍵字implements,OC中通過在父類名後的“<>”中包裹協定名,實作隻在.m檔案中實作,頭檔案中不必重複定義

@interface BusicessLogic : NSObject <NetworkClent>
           

當然協定也可以繼承協定,格式

@protocol  協定名  <父協定>

如果兩個協定中的方法互相調用對方作為參數,将造成循環依賴,而導緻編譯錯誤

例如:

@protocol A

-(void) testA:(id<B>) b ;

@end

@protocol B

-(void) testB:(id<A>) a ;

@end

可以采用在協定聲明前加入  @protocol 協定名  來解決

告訴編譯器這是個協定,就不再導入其頭檔案了

如何擴充類那?

這就是類别的作用

類别的聲明:在要聲明的類(非父類)後加入圓括号,括号中放置類别名

在字典類中做擴充

@interface NSMutableDictionary (GUID)

-(void) appendGuid;

@end

類别不僅能擴充對象方法,還可以擴充類方法

類别缺點:不能添加成員變量

那麼如果需要引入成員那?可以通過關聯引用的方式,首先這種方式并不是真的引入成員變量,也沒有與之關聯的屬性和存取器方法,僅僅是一個與引入類的執行個體關聯的一個存儲器

可以通過oc提供的運作時函數objc_setAssociatedObject。該函數接收4 個參數:想關聯到資料的對象、擷取資料的鍵值、存儲引用

的值以及一個關聯政策,關聯政策定義了如何管理存儲值的記憶體

關聯之後的取值:objc_getAssociatedObject

該函數接收兩個參數,資料關聯的對象以及關聯資料時指定的鍵值。

最後調用Objective-C 函數

objc_setAssociatedObject 移除關聯,不過這次傳入nil 作為要關聯的值

關聯政策取值:

OBJC_ASSOCIATION_ASSIGN 指定值将被簡單指派。沒有使用保留和釋放

OBJC_ASSOCIATION_RETAIN_NONATOMIC 指定值通過非線程安全的方式指派并保留

OBJC_ASSOCIATION_COPY_NONATOMIC 指定值通過非線程安全的方式複制

OBJC_ASSOCIATION_RETAIN 指定值通過線程安全的方式指派并保留

OBJC_ASSOCIATION_COPY 指定值通過線程安全的方式複制