沒有直接的方法來獲取你擁有的一塊內存,並將其「廉價」轉換成一個NSArray--畢竟,框架需要擁有該內存,並且它不知道你擁有的內存它來自(malloc,堆棧等)。如果initWithArrayWrapElementsInObjects有一個簡便的方法,它本身需要在內部完成你所推測的內容:遍歷你提供的內存並向它自己添加項目(它可能是框架可以像memcpy一樣快速地完成,但是誰知道)。
你可以解決這個問題的一種方法(也許是一種有趣的學習練習)是通過實際創建你自己的NSArray子類來完全按照你的想法來管理內存(也就是說,你可以用你想要的任何語義創建和初始化),但作爲一個NSArray會對外部世界表現出來。您可以通過繼承NSArray並實現方法count:
和objectAtIndex:
來執行此操作,以便操作任何內存。顯然,你需要在init/dealloc等方法中實現對自己內存的管理。見「子類別註釋」下的http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html 。
這裏的設計討論取決於您的數據是什麼樣子。 NSArray當然期望它的項目是Obj-C引用(類型爲id
),而不僅僅是任意的數據塊。如果你的C風格的數組持有結構或者其他一些不是對象引用的原始值,那麼這種技術對你來說真的不起作用 - NSArray的接口永遠不會滿足於非引用項目。
最後一點:你提到了一個NSMutableArray和「創建」一個NSArray。你應該知道一個NSMutableArray已經是一個NSArray了,因爲它是一個子類。你可以在任何你想要NSArray的地方使用NSMutableArray的一個實例,而不需要創建它的一個新副本。
UPDATE:錯過了關於包含浮點數組的註釋。是的,你在這裏有點麻煩。 NSArrays需要對象。如果容量翻倍是昂貴的部分(如另一張海報註釋),那麼請嘗試initWithCapacity :.如果是把對象類型的花車裝箱/拆箱,那麼你就無能爲力。
我已經創建了(但沒有得心應手)一對非常簡單的類(稱爲像MYArray和MYMutableArray),旨在包裝這種類型的數據與類NSArray的方法。但它們不能與NSArrays互換。你必須有意地使用它們。
UPDATE#2。我知道這個問題已經過去了很久了,但我只是重新審視它,並意識到實際上在這個具體案例中有一種巧妙的解決方法。 (你想從C樣式的float數組中獲得不可變的NSArray
)。您可以創建的NSArray一個包裝浮點值的自定義子類,當他們通過原語只訪問它們轉換爲對象。這在某些角落(?)可能會有性能缺陷,但它確實能夠滿足您的要求:
@interface FloatProxyArray : NSArray
{
float * values;
NSUInteger count;
}
- (id)initWithCArray:(float *)arrayOfFloats count:(int)numberOfValues;
@end
。
@implementation FloatProxyArray
- (id)initWithCArray:(float *)arrayOfFloats count:(int)numberOfValues
{
if ((self = [super init])) {
values = (float *)malloc(numberOfValues * sizeof(float));
if (!values) {
[self release]; return nil;
}
memcpy(values, arrayOfFloats, numberOfValues * sizeof(float));
count = numberOfValues;
}
return self;
}
- (void)dealloc
{
free(values);
[super dealloc]
}
- (NSUInteger)count
{
return count;
}
- (id)objectAtIndex:(NSUInteger)index
{
if (index >= count) {
[NSException raise:NSRangeException format:@""];
return nil;
}
float val = values[index];
return [NSNumber numberWithFloat:val];
}
@end
(NB寫在不編譯/測試編輯。)
謝謝!這就說得通了。 – 2010-01-03 17:11:56