2014-12-05 113 views
2

我想獲取存儲在NSValue中的對象的指針,以便我可以對其進行修改。要點是這樣的:從`NSValue`獲取緩衝區指針

// Get a pointer to the value's buffer (it'd be void*, I guess). 
CGRect *myRect = [rectValue getPointer]; 

// Modify the rectangle. 
myRect->origin = CGPointMake(10, 10); 

我注意到NSValue有方法pointerValue,但文件說:

爲指針無效的值。如果未創建值對象來保存指針大小的數據項,則結果是未定義的。

...所以這似乎只適用於指針的值,這不是,這是一個CGRect

順便說一句,如果答案是「你不能這樣做」,仍然一個很好的答案,據我擔心:-)的,爲什麼不將是有趣的解釋,因爲它似乎就像API中一個非常明顯的缺席一樣。

回答

1

我相信答案是確實,「你不能這樣做。」 *

下面是我想到,爲什麼這應該是這樣的幾個原因。

  • NSValue,像在Objective-C許多核心數據類型,是不可改變。允許你抓取實例中存儲的內部值的指針不會對它的不變性有好處。
  • 訪問這樣一個指針將不可避免地返回一個void *。這繞開了編譯器的所有類型檢查的能力,這是爲了您自己的好處!
  • 一般而言,班級儘量隱藏儘可能遠離外部世界的內部狀態和功能,並小心管理與外部世界的交互。設想一個想要知道每次訪問其存儲值爲CGRect(據我所知,NSValue實際上並沒有監視這個)的例子的愚蠢情況。用指針,它不知道你什麼時候這樣做。然而,使用方法-[NSValue CGRectValue],您別無選擇,只能通知它。

與前兩個原因特別是面對,你甚至可以對自己說,以及如果所有的這是真的,爲什麼pointerValue存在?這可能會允許可變性,並且它可能允許指針不被類型檢查。好問題,但容易回答:如果你有一個指針創建NSValue實例 - 說,與+[NSValue valueWithPointer:],用於獲取該指針背出實例的唯一選擇是返回void *的方法。還有什麼會構成某種假設的方法

*的部分「不能」這裏是一個相對的概念。例如,如果您知道內部密鑰名稱,則valueForKey:可能仍然有效。

+0

感謝您的回答 - 我很高興我不是失去了一些東西,但我不知道我真的與你的第一個兩分同意! :-)因此,有可能是一個可變的變種(如許多核心類型),或指向const的空隙可以返回。 'NSValue'的設置已經假定你在實例化時獲得了正確的類型。在這種情況下,你期望的類型可以被指定,所以'NSValue'可以檢查它是什麼?但是......我認爲你最後的觀點是合理的 - 'NSNumber在類型之間執行強制轉換,這是一個void指針根本不能執行的操作。也許'NSData'可以替代嗎? – Benjohn 2014-12-05 23:19:21

+0

偉大的觀點,@ Benjohn。我會說,'NSValue'的可變變體不會是一個非常有價值的補充,因爲這個類只是一個單一的 - 典型的C風格數據的薄對象包裝器。能夠改變這些數據並不會那麼有用,並且會以可能增加錯誤的複雜性和機會的代價(例如,傳遞一個'NSMutableValue',你認爲它是不可變的,但是然後從下面改變您)。另外,創建新的'NSValue'是非常低的開銷,所以幾乎沒有什麼優勢可以解決這個問題。 – ravron 2014-12-06 00:51:44

+0

嘿 - 有趣的是,在這種情況下,我並不關心運行時間的開銷。這是我打擾過的代碼開銷 - 解包,更新大小並重新打包,v使用指針解引用來設置結構的size屬性。也許這是我應該建立的課程:-) – Benjohn 2014-12-06 20:22:24