2

對,我很困惑。如果實例respondsToSelector - 爲什麼仍然是「無法識別的選擇器發送到實例」?

這就是所謂的NSTableView子10.8和我們可以從the docs學習和頭NSTableView實現NSDraggingSource所以都應該是不錯的:

if ([super respondsToSelector:@selector(draggingSession:movedToPoint:)]) 
    [super draggingSession:session movedToPoint:screenPoint]; 

當含有方法在子類(的draggingSession:movedToPoint:覆蓋)被調用,然而第二行引發了心愛的'無法識別的選擇器發送到實例0x1054092c0'異常。

有人可以解釋這裏發生了什麼?

+3

在你的例子中設置一個異常斷點並檢查實例的類(0x1054092c0')。 - 還要注意,''superrespondsToSelector:sel]'與'[self.respondsToSelector:sel]'相同*(它只是調用'respondsToSelector:'的超級實現,你可能不會*覆蓋,但是仍然檢查'self'中的選擇器)。 –

+0

顯示完整的異常消息。 –

回答

3

首先,[super respondsToSelector:@selector(draggingSession:movedToPoint:)]是一樣的[self respondsToSelector:@selector(draggingSession:movedToPoint:)]super允許您調用給定方法的超類實現;在這種情況下,respondsToSelector:。但是如果你的類(或者這個對象的任何類)不覆蓋-respondsToSelector:(99.9%的類不需要覆蓋-respondsToSelector:),那麼超類的實現與self類的實現相同。基本上,在這兩種情況下,您都在檢查當前對象(self)是否響應選擇器。

所以,你所看到的是這樣的:self響應選擇器,但是這個類的超類沒有選擇器的實現。那是什麼意思?無論是當前班級,還是當前班級之間的某個地方,作爲self的班級,此方法都已實施。這就是爲什麼self對此作出迴應。但是沒有超類的實現。

-1

感謝您的提示 -
這確實很好地工作:

if ([[self superclass] instancesRespondToSelector:@selector(draggingSession:movedToPoint:)]) 
    [super draggingSession:session movedToPoint:screenPoint]; 
+0

這是錯誤的。 '[self superclass]'不一定就是這個代碼所在的類的超類。只有當'self'類是這個代碼所在的類時。如果'self'的類是這個類的子類,那麼'[self superclass]'是這個類或它的某個子類,因此檢查'[self superclass]'的實例是否響應是不夠的。 – newacct

+0

通讀這個問題 - 這段代碼顯然是從同一個子類中調用的'super'在開始的例子中被調用,所以這段代碼對發佈的場景是完全有效的並且解決了這個問題 – ATV

+0

您正在誤讀我的意思。假設這段代碼在'Foo'類中,好嗎?而'Foo'的超類是'Bar',好嗎? '[self superclass]'不一定是'Bar',因爲'[self class]'不一定是'Foo'。 – newacct

0

正確的代碼實際上是:

if ([[NSTableView class] instancesRespondToSelector:@selector(draggingSession:movedToPoint:)]) 
    [super draggingSession:session movedToPoint:screenPoint]; 

正如newacct指出,super是指其中所述方法被實施的類的超類,而[self superclass]是在其上它是實例的超類稱爲,這可能是您的自定義類的子類(NSTableView的孫子)。當然,你不可能創建這樣一個子類,但你也可以做正確的事情,而且這個代碼無論如何都是清晰的。

相關問題