2015-04-03 265 views
3

這是相當先進的東西。我將一些運行時代碼作爲一個側面項目搞亂了。我試圖解決的問題是這樣的:如果我有一個id類型的對象,並且該對象可以是一個字符串,一個類或一個協議,我該如何判斷它是什麼?iOS:如何判斷類型id的對象是類還是協議

例如,這裏是一些代碼,我搞亂:

[objArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
    if ([obj isKindOfClass:[NSString class]]) { 
     // Do something with the string ... 
    } else if (... obj is a Protocol ...) { 
     // Do something with the protocol ... 
    } else if (... obj is a Class ...) { 
     // Do something with the class ... 
    } else { 
     // It's something we are not interested in! 
    } 
}]; 

到現在爲止我已經沒有問題,存儲爲的NSString,陣列中的類和協議實例的分類和其他的一切都是精細。我需要檢測它們的原因很簡單,就是我無法控制進入該代碼的內容。所以我需要確定循環處理的obj在做什麼之前。

我一直在嘗試各種運行時功能和東西,但到目前爲止沒有運氣,如果確定什麼對象是。

任何人都試過類似的東西?

+0

協議發現被定義爲因此,它們實際上可以存儲在NSArrays和一個類型NSObject的的喜歡。我已經很成功地做到了這一點。很顯然,我正在做的事情是一個非常動態的東西,而且它通常只是Objective C代碼的一部分。 – drekka 2015-04-03 13:35:22

回答

2

因爲議定書子類NSObject的你可以檢測到它以同樣的方式對其他任何類。有趣的是,協議類沒有公共接口。

類型的對象ID可以是一個類或一個類的一個實例,因此,如果它是一類第一我將測試,和如果失敗,這是爲此使用字符串比較一個類的實例和確定類名稱。爲協議比較@「協議」

例 -

// assign the object to inspect 
id obj = //... 
NSString *className; 
// test for Class type first 
if (object_isClass(obj)) { 
// it's a Class... inspect further... 
className = NSStringFromClass(obj); 
if ([className isEqualToString:@"Protocol"]) { /* Protocol Class */ } 
} 
else { 
// must be an instance - get the class name 
className = NSStringFromClass([obj class]); 

// test for instance of Protocol class 
if ([className isEqualToString:@"Protocol"]) { /* Protocol instance */ } 

// continue testing for any other classes here... 

} 

NSStringFromClass在Foundation Functions Reference

+0

謝謝。這幾乎是我要去的地方。 – drekka 2015-04-04 11:38:47

2

我現在可能已經找到了解決方案。

要測試一個ID爲A類:

NSLog(@"isClass %s", object_isClass(obj) ? "yes":"no"); 

要測試如果ID是一個協議:

NSLog(@"isProtocol %s", object_getClass(obj) == objc_getClass("Protocol") ? "yes":"NO"); 

這些似乎工作,但我認爲有可能是一個更好的辦法做協議檢查。

相關問題