2009-10-05 86 views
2

我有一個需要發送消息的Objective-C類中的指針。指針可能是任何東西,所以我需要確保它在發送消息之前會響應我的消息。下面是我用做檢查的功能:如何知道指針是否是NSObject?

int delegatePreparedForSelector(id delegate, SEL aSelector) { 
    if (delegate 
     && [delegate isKindOfClass:[NSObject class]] 
     && [delegate respondsToSelector:aSelector]) { 
     return YES; 
    } 
    return NO; 
} 

的問題是,有時委託指針是struct objc-object *,我得到一個壞EXC_BAD_ACCESS訪問錯誤,當我發送isKindOfClass消息。

是否有更好的測試我應該用來確定委託人是否會回覆我的消息?

回答

5

聽起來好像你的委託在調用之前被拋棄了,而不是這個代碼有任何必然的錯誤。

另外,您可以對參數執行協議實現,例如:id<MyDelegateProtocol> delegate而不是僅使用裸號。

+0

這是問題所在。當委託被解除分配並設置爲'nil'時,它的類型被設置爲'struct objc_object *'我在調試器中看到的。 – kubi 2009-10-05 21:22:43

+0

如果委託人爲零,則上述情況不會崩潰.... – bbum 2009-10-05 22:11:43

+1

零與解除分配 – slf 2009-10-06 13:33:01

-1

委託指針指向型結構objc_object引起問題是混亂的,如在OBJ - C的所有對象都是類型的(挖入OBJ-C的對象):

struct objc_object 
{ 
    struct objc_class *isa; 
    /* extra stuff */ 
}; 

的* ISA指向一個班..一些班。因此,您設置爲委託的對象可能不存在或指向錯誤的內存。

+0

不能使用@try捕捉信號('EXC_BAD_ACCESS')。 – 2009-10-05 20:41:47

+0

woops。你是對的。那麼他將不得不承擔責任並追查該蟲是否存在。 – pxl 2009-10-05 20:46:35

6

等等,你真的指的是指針可以是任何東西嗎?像void *指向一大塊原始malloc'ed內存,或一個objc_object不派生自NSObject?如果確實如此,那麼無法安全地進行這項工作。這相當於說「不廢棄這個指針,我怎麼知道解除引用是安全的?」唯一的辦法就是有先驗知識,無論傳給你什麼都不會給你一個不好的指針。

您可以嘗試編寫一些信號處理程序代碼來清除EXEC_BAD_ACCESS,但最終它會慢慢地,很差地工作,並屏蔽大量其他實際的錯誤。實際上,你對傳遞的內容有一些限制,或者你需要重新設計你的項目的這一部分。

相關問題