Nie ma bezpośredniego sposobu na zrobienie kropli pamięci, którą posiadasz, i "konwersję" jej taniej na NSArray - w końcu ramy będą musiały posiadać tę pamięć, a ona nie wie, gdzie jesteś to z (malloc, stack, itp.). Gdyby istniała wygodna metoda dla initWithArrayWrapElementsInObjects, sama musiałaby wewnętrznie przewidzieć, co się domyśla: iterować po dostarczonej pamięci i dodawać elementy do siebie (prawdopodobnie framework mógłby to zrobić tak szybko, jak memcpy, ale kto wie).
Jednym ze sposobów poradzenia sobie z tym (i prawdopodobnie zabawnym ćwiczeniem) jest stworzenie własnej podklasy NSArray, która zarządza pamięcią dokładnie tak, jak chcesz (np. Pozwala tworzyć i uruchamiać dowolną semantykę), ale który zachowuje się do zewnętrznego świata, tak jak zrobiłby to NSArray. Możesz to zrobić, dziedzicząc z NSArray i implementując metody, które będą działać na dowolnej pamięci, na którą się trzymasz. Oczywiście, musisz również zaimplementować zarządzanie własną pamięcią w metodach init/dealloc, etc. Zobacz tę stronę http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html w "Uwagi dotyczące podkatalogów".
Dyskusja na temat projektu zależy od tego, jakie są Twoje dane. NSArray, oczywiście, oczekuje, że jego elementy będą referencjami Obj-C (typu id
), a nie tylko dowolnymi porcjami danych. Jeśli twoja tablica w stylu C trzyma struktury lub inne prymitywne wartości, które nie są odniesieniami do obiektów, technika ta nie będzie działać dla ciebie - interfejs NSArray nigdy nie będzie zadowolony z elementów niezwiązanych z referencjami.
Ostatnia uwaga: wspomniałeś o wzięciu NSMutableArray i "stworzeniu" NSArray razem z nim. Należy mieć świadomość, że NSMutableArray jest już NSArray, ponieważ jest to podklasa. Możesz użyć instancji NSMutableArray w dowolnym miejscu, gdzie chcesz NSArray, bez tworzenia nowej kopii.
UPDATE: Pominięto notatkę o macierzy zawierającej zmienne. Tak, jesteś tu trochę zakręcony. NSArrays chce obiektów. Jeśli podwojenie wydajności było kosztowną częścią (jak zauważa inny plakat), spróbuj initWithCapacity :. Jeśli chodzi o boksowanie/rozpakowywanie paczek do typów obiektów, nic nie możesz zrobić.
Stworzyłem (ale nie mam pod ręką) parę bardzo prostych klas (zwanych jak MYArray i MYMutableArray), które są przeznaczone do zawijania właśnie tego rodzaju danych za pomocą metod NSArray na nich. Ale nie są one zamienne z NSArrays. Musisz ich użyć celowo.
AKTUALIZACJA # 2. Wiem, że minęły wieki od czasu, gdy to pytanie było na żywo, ale po prostu ponownie je przeanalizowałem i zdałem sobie sprawę, że w tym konkretnym przypadku jest to dość sprytny sposób. (Chcesz niezmiennego NSArray
z macierzy float w stylu C). Możesz utworzyć niestandardową podklasę NSArray, która opakowuje wartości zmiennoprzecinkowe i konwertuje je tylko do obiektów, gdy są one dostępne przez prymitywy. Może to mieć pułapki wydajnościowe w niektórych zakątkach (?), Ale spełnia dokładnie Twoje wymagania:
@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 pisane w edytorze bez kompilowania/testowanie).
Dzięki! To ma sens. –