Vytvoření NSArray inicializuje počtu N, všichni stejný objekt

hlasů
9

Chci vytvořit NSArray předměty stejné hodnoty (řekněme NSNumber vše inicializována na hodnotu 1), ale počet je založen na jiné proměnné. Nezdá se, že je způsob, jak to udělat s některou z intializers pro NSArray kromě jednoho, který se zabývá C-styl pole.

Jakýkoliv nápad, pokud je krátký způsob, jak to udělat?

To je to, co jsem hledal:

NSArray *array = [[NSArray alloc] initWithObject:[NSNumber numberWithInt:0]
                                           count:anIntVariable];

NSNumber je jen jeden příklad tady, by to mohlo být v podstatě jakýkoliv NSObject.

Položena 01/07/2009 v 23:20
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
14

Nejtěsnější kód jsem byl schopen psát pro to je:

id numbers[n];
for (int x = 0; x < n; ++x)
    numbers[x] = [NSNumber numberWithInt:0];
id array = [NSArray arrayWithObjects:numbers count:n];

Toto pracuje, protože si můžete vytvořit runtime délka stanovena C-pole s C99, který Xcode používá ve výchozím nastavení.

V případě, že jsou všechny stejné hodnoty, můžete také použít memset (i když obsazení do int je nemravné):

id numbers[n];
memset(numbers, (int)[NSNumber numberWithInt:0], n);
id array = [NSArray arrayWithObjects:numbers count:n];

Pokud víte, kolik objektů budete potřebovat, pak tento kód by měl fungovat, i když nebyly testovány to:

id array = [NSArray arrayWithObjects:(id[5]){[NSNumber numberWithInt:0]} count:5];
Odpovězeno 02/11/2011 v 11:58
zdroj uživatelem

hlasů
3

Nevidím žádný důvod, proč tato struktura ve třetím měnitelného formátu by bylo užitečné, ale jsem si jist, že máte své důvody.

Nemyslím si, že budete mít jinou možnost, než použít NSMutableArray, postavit se smyčky for, a pokud je to opravdu důležité, že výsledek nemusí být proměnlivé, zkonstruovat NSArray a používat arrayWithArray:

Odpovězeno 01/07/2009 v 23:38
zdroj uživatelem

hlasů
2

Pravděpodobně důvod, není tam žádná taková metoda na NSArray je, že sémantiku nejsou dobře definovány. Pro váš případ s neměnnou NSNumber, pak všechny různé sémantiku jsou rovnocenné, ale představte si, že objekt, který se dodává byl proměnlivý objekt, jako například NSMutableString.

Existují tři různé sémantiku:

  • zachovat - byste skončit s deseti ukazatelů na stejné měnitelného řetězce, a měnící se některý změní všemi deseti.

  • copy - byste skončit s deseti ukazatele na stejné neměnné řetězec, případně deset různých ukazatelů na immeduable řetězce se stejnou hodnotou, ale tak jako tak byste nebyli schopni změnit některé z nich.

  • mutableCopy - byste skončit s deseti různými nestálých objektů typu string, přičemž kterýkoli z nich byste mohli nezávisle měnit.

Takže Apple mohl napsat tři varianty způsobu, nebo mít nějaký parametr pro kontrolu sémantiku, z nichž oba jsou ošklivé, a tak místo toho ho nechal na vás psát kód. Chcete-li, můžete ho přidat jako metoda kategorie NSArray, prostě být jisti, že jste pochopili sémantické možnosti a dát jasně najevo.

Metoda:

-(id)initWithArray:(NSArray *)array copyItems:(BOOL)flag

má stejný problém.

Quinn řešení využívající arrayWithObjects: počet: je poměrně dobrá, nejspíš asi nejlepší, co můžete získat pro obecný případ. Dejte ji v kategorii NSArray a to je asi tak dobré, jak to dostane.

Odpovězeno 02/07/2009 v 04:11
zdroj uživatelem

hlasů
2

Souhlasím s @mmc , ujistěte se, že máte skutečný důvod mít takovou strukturu (namísto právě pomocí stejného objektu n-krát), ale budu předpokládat, že jste dělat.

Tam je další způsob, jak sestrojit neměnný pole, který by byl o něco rychlejší, ale vyžaduje vytvoření C pole objektů a její předání do NSArray je + arrayWithObject: počet: metoda (která vrací autoreleased pole, mysl vy) takto:

id anObject = [NSNumber numberWithInt:0];
id* buffer = (id*) malloc(sizeof(id) * anIntVariable);
for (int i = 0; i < anIntVariable; i++)
  buffer[i] = anObject;
NSArray* array = [NSArray arrayWithObjects:buffer count:anIntVariable];
free(buffer);

Ty by mohly dosáhnout totéž s ještě složitější ukazatel matematiku, ale zisky jsou poměrně triviální. Komentář, pokud máte zájem tak jako tak.

Odpovězeno 02/07/2009 v 00:09
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more