2010-04-18 54 views
1

我知道在objective-c運行時有一些函數允許你直接創建對象,比如class_createInstance。我想知道的是,如果有什麼實際使用這些函數,而不是根類(NSObject)的alloc方法。我認爲像KVC綁定這樣的東西可能會有,但那些不在iPhone OS上(據我所知,如果我錯了,請糾正我),那麼有沒有什麼可以做到這一點?是否在不經過alloc的情況下創建了objective-c中的對象?

如果你想知道/它很重要,我期望分配一個實例的大小,以繞過objc運行時,通過聲明一個類沒有ivars,但覆蓋+ alloc方法並調用class_createInstance (自我,myivarsbytes)。

感謝

編輯 我想我需要更加具體。我在運行時將類添加到運行時,並可能卸載並重新加載相同類的更改版本。到目前爲止,我已經解決了大部分問題,因爲class_addMethod之類的東西,但是在類註冊後,沒有與ivars等效的東西。我所能想到的兩種解決方案,就運行時而言,沒有實際的ivars,但是覆蓋alloc以確保我有足夠的空間通過extraBytes,或者聲明一個指向我所有實際ivars的指針,那我顯然可以做任何我想要的。我寧願使用前一種策略,但有很多事情可能會出錯,例如,如果某些事情沒有通過我的重載alloc方法分配對象的實例。有誰知道這些事情之一?

回答

1

我不知道你是否試圖改變現有類的行爲,這是不安全的,或試圖爲自己的自定義類做一些NSObject的直接子類,這可能是。

幾乎所有在實踐中看到的NSString都是私有子類的實例,並且該子類爲該對象的內聯字符串分配空間。就像,不是包含一個指向char *的指針,字符數據就在對象中的ivars之後。 NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone)中的extraBytes參數可用於此目的。

因此,一方面,是的,你可以把這樣的技巧。另一方面,你需要知道你在做你的的東西。如果您嘗試使用NSString的私有子類(這是私有的,因此您只通過運行時自檢進行交互)做類似的事情,那麼您可能會發生衝突。

有幾個公共可可類,也做這樣的東西,所以你最好,如果你的類直接從NSObject的繼承。 NSLock就是其中之一。 NSLock的自定義子類在內存中的佈局看起來像{ isa, <ivars of NSLock> <ivars of subclass of NSLock> <more NSLock stuff, space reserved using the extraBytes parameter> }

而且,只爲它赫克,注意+ ALLOC電話+ allocWithZone:和+ allocWithZone:是較常見的覆蓋點。

+0

哦,但我剛剛看到你正在嘗試做什麼。好吧,爲了好玩,可以玩它,但我不會嘗試它的實際使用。這就是那種讓你後悔的黑客行爲,希望你把它吸了起來,並以正常的方式去做。如果在框架中有這樣的通用黑客攻擊是很好的,那麼可以說,如果將gc添加到手機中,它可以正確適應垃圾收集。你可以把伊娃做成ivars的東西,或者你可能想看看objc_getAssociatedObject/objc_setAssociatedObject。這些基本上自動化有一個額外的東西在你的對象字典。 – Ken 2010-04-18 20:52:08

+0

另一方面,如果這是爲了加快編譯/運行/調試周期,並且您在應用中發佈的內容將不會使用它,那聽起來很有趣,就是爲了它。 :-)雖然..你可能想看看ZeroLink,。這是爲了加速開發,並按照您的描述工作,重新加載代碼等。蘋果公司放棄了它 - 通常解決一些奇怪的問題是「關閉zerolink」。 – Ken 2010-04-18 20:59:19

+0

我投了這個allocWithZone:和NSLock的例子,但我不能真正接受,因爲它不符合不通過allocWithZone調用的東西的標準。此外,這將是生產代碼的基礎,所以我可能不會這樣做,因爲你的NSLock示例 - 它最終會打破使用該技術的任何NSLock子類。 – 2010-04-19 00:02:27

0

我不知道你爲什麼想要做你的建議 - 我沒有看到任何理由你不能做到這一點,但根據this post,通常沒有理由使用直接(我不知道任何具體使用它的東西)。 class_createInstance也不考慮內存區域或alloc使用的其他可能的優化。如果你只是想隱藏你的ivars,那麼有better ways

編輯:我認爲你正在尋找class_addIvar函數,它(顧名思義)動態地添加一個ivar到一個類。它只適用於新的運行時,所以它不會在模擬器上工作,但它可以在iPhone上運行。

編輯2:只是要完全清楚(如果它還沒有),你一定可以依靠總是被調用的allocWithZone。基本可可級,例如NSStringNSArray,覆蓋allocWithZoneclass_createInstance幾乎從不使用,除了在運行時級別,所以你不必擔心可可在你的類中使用它的任何部分。所以對原始問題的答案是「否」(或者更具體地說,至少據我所知,有時創建對象時沒有alloc,但不是沒有allocWithZone)。

+0

如果您仔細閱讀文檔,您會發現添加ivars只能在分配類和註冊時發生。在這個問題中,我指定我需要能夠加載/卸載相同類的變量,例如使用不同的ivars。無法從運行時卸載類,或者將其替換。 – 2010-04-18 23:46:49

+0

對不起,我沒有看到。爲了回答你原來的問題(我認爲我現在明白了),可以認爲總是調用'allocWithZone'是安全的 - 許多基本的Cocoa類(例如NSArray和NSString)被實現爲類集羣,並且覆蓋' allocWithZone'。此外,萬一它有幫助,你通常調用'NSAllocateObject'而不是'class_createInstance'(我實際上不確定確切的區別)。 – shosti 2010-04-19 02:45:09

+0

NSAllocateObject調用class_createInstance。所有的NS *函數都包裝了相同的Objective-C運行時函數。 – rpetrich 2010-04-19 04:38:33

-1

那麼沒有什麼技術上阻止你從重寫alloc。只需在你的類中創建一個名爲+ alloc的方法。我無法想象你爲什麼需要的任何理由。

-1

聽起來就像你在努力管理內存。讓OS在創建對象時動態分配內存。如果您使用的太多,操作系統會發出通知,說明您已接近極限。在這一點上,你可以釋放你不再需要的東西。

如果你需要,你必須使用技巧這麼多內存,您的實現可能需要在覈心層面反思,而不是試圖以適應你的方形設計到iPhone OS的圓孔。

只是我的意見根據您提供的信息。

+0

你顯然不知道這個問題是問,並且絕對沒有問題的功能熟悉,否則它將立即明確表示,它使用的內存爲任何正常的技術完全相同的量,特別是因爲它往往是什麼用來實現可可分配,或者你認爲我是一個白癡,並沒有意識到自己 – 2010-04-18 23:53:09

相關問題