偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Cocoa 基本原理指南 內(nèi)省介紹

移動(dòng)開(kāi)發(fā) iOS
內(nèi)省(Introspection)是面向?qū)ο笳Z(yǔ)言和環(huán)境的一個(gè)強(qiáng)大特性,Objective-C和Cocoa在這個(gè)方面尤其的豐富。

Cocoa 基本原理指南 內(nèi)省介紹是本文介紹的內(nèi)容,內(nèi)省(Introspection)是面向?qū)ο笳Z(yǔ)言和環(huán)境的一個(gè)強(qiáng)大特性,Objective-C和Cocoa在這個(gè)方面尤其的豐富。內(nèi)省是對(duì)象揭示自己作為一個(gè)運(yùn)行時(shí)對(duì)象的詳細(xì)信息的一種能力。這些詳細(xì)信息包括對(duì)象在繼承樹(shù)上的位置,對(duì)象是否遵循特定的協(xié)議,以及是否可以響應(yīng)特定的消息。NSObject協(xié)議和類定義了很多內(nèi)省方法,用于查詢運(yùn)行時(shí)信息,以便根據(jù)對(duì)象的特征進(jìn)行識(shí)別。

明智地使用內(nèi)省可以使面向?qū)ο蟮某绦蚋痈咝Ш蛷?qiáng)壯。它有助于避免錯(cuò)誤地進(jìn)行消息派發(fā)、錯(cuò)誤地假設(shè)對(duì)象相等、以及類似的問(wèn)題。下面的部分將介紹如何在代碼中有效地使用NSObject的內(nèi)省方法。

評(píng)估繼承關(guān)系

一旦您知道一個(gè)對(duì)象屬于什么類,就可能已經(jīng)相當(dāng)了解這個(gè)對(duì)象了。您可以知道它具有什么能力、哪些屬性、以及可以響應(yīng)哪些消息。即使在內(nèi)省之后不能了解對(duì)象所屬的類,也可以知道該對(duì)象不能響應(yīng)特定的消息。

NSObject協(xié)議聲明了幾個(gè)方法,用于確定對(duì)象在類層次中的位置。這些方法在不同粒度上進(jìn)行操作,比如class和superclass實(shí)例方法分別返回代表類和超類的Class對(duì)象。使用這些方法需要將一個(gè)Class對(duì)象和另一個(gè)進(jìn)行對(duì)比。

使用類和超類的方法

  1. // ...   
  2. while ( id anObject = [objectEnumerator nextObject] ) {   
  3.     if ( [self class] == [anObject superclass] ) {   
  4.         // do something appropriate...   
  5.     }   
  6. }  

請(qǐng)注意:有些時(shí)候您需要通過(guò)class或superclass方法得到正確的類消息接收者。

更加常見(jiàn)的是檢查對(duì)象類的從屬關(guān)系,這種情況下您需要向該對(duì)象發(fā)送isKindOfClass:或isMemberOfClass:消息。前一個(gè)方法返回接收者是否為給定類或其繼承類的實(shí)例,isMemberOfClass:消息則告訴您接收者是否為指定類的實(shí)例。isKindOfClass: 方法通常更有用,因?yàn)橥ㄟ^(guò)它可以知道是否可以向該對(duì)象發(fā)送一系列消息??紤]列表2-8中的代碼片斷:

 使用isKindOfClass:方法

  1. if ([item isKindOfClass:[NSData class]]) {   
  2.     const unsigned char *bytes = [item bytes];   
  3.     unsigned int length = [item length];   
  4.     // ...   
  5. }  

確定tem對(duì)象是NSData類的繼承類的實(shí)例之后,代碼就知道可以向它發(fā)送NSData的bytes和length消息。假定item是NSMutableData類的一個(gè)實(shí)例,則isKindOfClass:和isMemberOfClass:之間的差別就變得更加明顯。如果您調(diào)用的是isMemberOfClass:,而不是isKindOfClass:,條件控制塊中的代碼將永遠(yuǎn)不會(huì)被執(zhí)行,因?yàn)閕tem并不是NSData類的實(shí)例,而是其子類NSMutableData的實(shí)例。

方法實(shí)現(xiàn)和協(xié)議遵循

NSObject還有兩個(gè)功能更加強(qiáng)大的內(nèi)省方法,即respondsToSelector:和conformsToProtocol:。這兩個(gè)方法分別告訴您一個(gè)對(duì)象是否實(shí)現(xiàn)特定的方法,以及是否遵循指定的正式協(xié)議(即該對(duì)象是否采納了該協(xié)議,且實(shí)現(xiàn)了該協(xié)議的所有方法)。

在代碼中,您可以在類似的情況下使用這些方法。通過(guò)這些方法,您可以在將消息或消息集合發(fā)送給某些潛在的匿名對(duì)象之前,確定它們是否可以正確地進(jìn)行響應(yīng)。在發(fā)送消息之前進(jìn)行檢查可以避免由不能識(shí)別的選擇器引起的運(yùn)行時(shí)例外。在實(shí)現(xiàn)非正式協(xié)議(這種協(xié)議是委托技術(shù)的基礎(chǔ))時(shí),Application Kit就是在調(diào)用委托方法之前檢查委托對(duì)象是否實(shí)現(xiàn)該方法(通過(guò)respondsToSelector:方法)。

顯示了如何在代碼中使用respondsToSelector:方法。

使用respondsToSelector:方法

  1. - (void)doCommandBySelector:(SEL)aSelector {   
  2.     if ([self respondsToSelector:aSelector]) {   
  3.         [self performSelector:aSelector withObject:nil];   
  4.     } else {   
  5.         [_client doCommandBySelector:aSelector];   
  6.     }   
  7. }  

顯示如何在代碼中使用conformsToProtocol:方法:

使用conformsToProtocol:方法

  1. // ...   
  2. if (!([((id)testObject) conformsToProtocol:@protocol(NSMenuItem)])) {   
  3.     NSLog(@"Custom MenuItem, '%@', not loaded; it must conform to the   
  4.         'NSMenuItem' protocol.\n", [testObject class]);   
  5.     [testObject release];   
  6.     testObject = nil;   
  7. }  

對(duì)象的比較

hashisEqual:方法雖然不是嚴(yán)格的內(nèi)省方法,但是可以發(fā)揮類似的作用,是進(jìn)行對(duì)象的識(shí)別和比較時(shí)不可或缺的運(yùn)行時(shí)工具。它們并不向運(yùn)行環(huán)境查詢對(duì)象信息,而是依賴于具體類的比較邏輯。

hashisEqual:方法都在NSObject協(xié)議中聲明,且彼此關(guān)系緊密。實(shí)現(xiàn)hash方法必須返回一個(gè)整型數(shù),作為哈希表結(jié)構(gòu)中的表地址。兩個(gè)對(duì)象相等(isEqual:方法的判斷結(jié)果)意味著它們有相同的哈希值。如果您的對(duì)象可能被包含在象NSSet這樣的集合中,則需要定義hash方法,并確保該方法在兩個(gè)對(duì)象相等的時(shí)候返回相同的哈希值。NSObject類中缺省的isEqual:實(shí)現(xiàn)只是簡(jiǎn)單地檢查指針是否相等。

isEqual:的使用相當(dāng)直接,它將消息的接收者和通過(guò)參數(shù)傳入的對(duì)象進(jìn)行比較。對(duì)象的比較常??梢栽谶\(yùn)行時(shí)決定應(yīng)該對(duì)對(duì)象做些什么。如列表2-11所示,您可以通過(guò)isEqual:來(lái)確定是否執(zhí)行某一個(gè)動(dòng)作。在這個(gè)例子中,動(dòng)作是指保存被修改了的預(yù)置信息。

使用isEqual:方法

  1. - (void)saveDefaults {   
  2.     NSDictionary *prefs = [self preferences];   
  3.     if (![origValues isEqual:prefs])    
  4.         [Preferences savePreferencesToDefaults:prefs];   
  5. }  

如果您正在創(chuàng)建子類,則可能需要重載isEqual:方法,以進(jìn)一步檢查對(duì)象是否相等。子類可能定義額外的屬性,當(dāng)兩個(gè)實(shí)例被認(rèn)為相等時(shí),屬性的值必須相同。舉例來(lái)說(shuō),假定您創(chuàng)建一個(gè)名為MyWidget的NSObject子類,類中包含兩個(gè)實(shí)例變量:name和data。當(dāng)MyWidget的兩個(gè)實(shí)例被認(rèn)為是相等時(shí),這些變量必須具有相同的值。列表2-12顯示如何在MyWidget類中實(shí)現(xiàn)isEqual:方法。

重載isEqual:方法

  1. - (BOOL)isEqual:(id)other {   
  2.     if (other == self)    
  3.         return YES;   
  4.     if (!other || ![other isKindOfClass:[self class]])    
  5.         return NO;   
  6.     return [self isEqualToWidget:other];   
  7. }   
  8.     
  9. - (BOOL)isEqualToWidget:(MyWidget *)aWidget {   
  10.     if (self == aWidget)    
  11.         return YES;   
  12.     if (![(id)[self name] isEqual:[aWidget name]])   
  13.         return NO;   
  14.     if (![[self data] isEqualToData:[aWidget data]])   
  15.         return NO;   
  16.     return YES;   
  17. }  

isEqual:方法首先檢查指針的等同性,然后是類的等同性,***調(diào)用對(duì)象的比較器進(jìn)行比較。比較器的名稱指示出參與比較的對(duì)象的類名稱。這種類型的比較器對(duì)傳入的對(duì)象進(jìn)行強(qiáng)制類型檢查,是Cocoa中常見(jiàn)的約定,NSString的isEqualToString:和NSTimeZone的isEqualToTimeZone:就是兩個(gè)這樣的例子。特定類的比較器(在這個(gè)例子中是isEqualToWidget:)負(fù)責(zé)執(zhí)行name和data變量的等同性。

Cocoa框架的所有isEqualToType:方法中,nil都不是正當(dāng)?shù)膮?shù),這些方法的實(shí)現(xiàn)在接收到nil參數(shù)時(shí)會(huì)拋出例外。然而為了向后兼容,Cocoa框架中的isEqual:方法可以接收nil值,在這種情況下返回NO。

小結(jié):Cocoa 基本原理指南 內(nèi)省介紹的內(nèi)容介紹完了,希望本文對(duì)你有所幫助!

責(zé)任編輯:zhaolei 來(lái)源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-07-07 13:30:32

Cocoa Core

2011-07-07 14:46:10

Cocoa Xcode

2011-07-07 14:22:27

Cocoa 對(duì)象 生命周期

2011-08-10 19:33:09

Cocoa對(duì)象

2010-03-18 20:13:03

Java socket

2012-01-12 14:37:34

jQuery

2011-11-29 12:17:00

2009-02-24 09:43:00

IP電話原理

2021-02-08 21:40:04

SockmapBPF存儲(chǔ)

2016-08-17 23:53:29

網(wǎng)絡(luò)爬蟲(chóng)抓取系統(tǒng)

2013-04-07 14:09:55

Android應(yīng)用基本

2016-08-18 00:04:09

網(wǎng)絡(luò)爬蟲(chóng)抓取系統(tǒng)服務(wù)器

2019-11-28 10:45:28

ZooKeeper源碼分布式

2020-03-21 14:57:14

手機(jī)定位智能手機(jī)APP

2010-08-20 13:29:33

OFDM

2010-03-17 13:35:02

2009-06-11 09:56:09

MySQL Repli原理

2020-12-29 16:55:44

ZooKeeper運(yùn)維數(shù)據(jù)結(jié)構(gòu)

2012-09-28 10:12:55

2024-01-30 09:21:01

deltaFifo機(jī)制apiServer
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)