2014-03-29 18 views
1

B的子類是A的C子類是A的子類,當我創建CI做if((self = [NSKeyedUnarchiver unarchiveObjectWithFile:…])) { }的.M裏面C.的Objective-C:強制類是其他

所以儘管我設置在Ch中的超類是B(這是我想要的),當我從unarchiveObjectWithFile:創建C對象時,因爲這個對象是A的子類,我不能強制它成爲B的子類。(很難解釋對不起) 。

是否有任何解決方法???換句話說:當我有一個屬於A類的對象,並且我有另一個B類作爲A的子類時,那麼unarchiveObjectWithFile:可以成爲B的子類嗎? (至極被允許因爲B的子類)

回答

4

如果我理解正確的:第

如果您在解除封存歸檔的B然後一個實例,你得到的B一個實例,也爲A實例和C

然而,在非技術性的語言,一個子類是一切它的超類是一些額外的比特。您不能[*]獲取直接創建或從非存檔創建的超類實例,並將其創建爲其子類之一的實例 - 「額外位」不在那裏。

HTH

[*]有人評論之前:是的,這是不是在所有情況下都絕對真實,但你正在進入隱晦的,高度專業化和危險的水域。不要去那裏。

附錄

看來你可能是在改變類的對象是安全類別:你應該能夠類的實例更改爲一個子類提供子類增加了沒有實例變量或屬性。要做到這一點,你可以使用Objective-C runtime functions

id obj = ... some instance of class A 
object_setClass(obj, [B class]); // where B is a subclass of A which adds no properties or variables 

您還可以使用解檔類設置類。

不要隨便這樣做。考慮替代品,但有時候這是一個合適的解決方案。

+0

閱讀上面 – Godfather

+0

評論@ user588125 - 這聽起來像你有這些情況下,您可以安全地更改類之一,如果這樣去做,隨着運行時間的功能。你也可以考慮使用一個可用於替換方法的類別(而不是覆蓋它們) - 再次注意一個區域。 – CRD

+0

兩個註釋1:object_setClass不會在我的環境中退出,我不能在沒有錯誤的情況下鍵入它,我只是得到object_getClassName(id obj),但_setClass不存在。 2:這個解決方案不適合我。在這裏,我粘貼什麼問題是http://pastebin.com/M1aGZ7S3。我有一個SKEmitterNode,我使用XCode Buildin工具創建,所以當我解壓縮它時,我得到一個SKEmitterNode(A),但是我的所有SKEmitterNode的解壓有一些屬性和其他東西他們分享,所以我創建了一個發射器:SKSpriteNode(B )共享該功能,最後我創建Smoke:Emitter(C)並且執行[[C alloc] init] – Godfather

1

unarchiver想要創建相同類型的類,這是以前存檔的類,而這通常也是你想要的。

你可以看看使用setClass:forClassName:更改類,這將是未歸檔的,但你站在早晚破壞一切的好機會......


基於粒子評論:

另一種選擇是採用超類實例並將它包裝在你的子類實例中。因此,您可以歸檔和取消歸檔您的子類實例,並且它將包含超類實例。您的子類不直接響應您的任何方法都可以轉發到超類實例。

這樣,你有2個對象,但你不與任何篡改或依靠的,你沒有自己的類實現細節。

+0

好吧,我更好地解釋它:我已經創建了一個粒子發射器與XCode構建工具,至少DOESNT允許我改變它的類(我會把它代替SKEmitterNode(A)它的一個子類(B )。然後,當我解壓縮它時,我得到了A的一個實例,但我有一些功能添加到這些發射器。 – Godfather

+0

有趣...所以你的子類只是增加/覆蓋了一些方法?沒有新的屬性/實例變量?給'setClass:forClassName:'嘗試一下,但要保守你的編碼。我要用不同的選項來更新我的答案,儘管... – Wain

+0

是的,只是添加了一些方法,無論如何,我不知道如何在這裏使用'setClass:forClassName:'! http://pastebin.com/9i4TpUAA – Godfather

相關問題