C'è un buon modo per convertire un vector<int32_t>
in un NSArray
di NSNumber
oppure è in loop e si aggiunge a un NSMutableArray
praticamente l'unico modo?convertire std: vector in NSArray
risposta
Se si dispone di un vettore di oggetti, è possibile effettuare le seguenti operazioni:
NSArray *myArray = [NSArray arrayWithObjects:&vector[0] count:vector.size()];
Tuttavia, se il vettore contiene i tipi primitivi, come ad esempio NSInteger
, int
, float
, ecc, si dovrà manualmente loop i valori nel vettore e convertirli in un NSNumber
prima.
State molto attenti con questo approccio per quanto riguarda la durata degli oggetti del vettore! – Richard
Questo risponde alla mia domanda. Ho un 'vector
Questo non funziona per me. Ricevo "Impossibile inizializzare un parametro di tipo 'const __unsafe_unretained id *' con un valore di tipo ..." –
Sì, è possibile creare un NSArray
di NSInteger
s da un std::vector<NSInteger>
utilizzando il seguente approccio:
// thrown together as a quick demo. this could be improved.
NSArray * NSIntegerVectorToNSArrayOfNSIntegers(const std::vector<NSInteger>& vec) {
struct MONCallback {
static const void* retain(CFAllocatorRef allocator, const void* value) {
/* nothing to do */
return value;
}
static void release(CFAllocatorRef allocator, const void* value) {
/* nothing to do */
}
static CFStringRef copyDescription(const void* value) {
const NSInteger i(*(NSInteger*)&value);
return CFStringCreateWithFormat(0, 0, CFSTR("MON - %d"), i);
}
static Boolean equal(const void* value1, const void* value2) {
const NSInteger a(*(NSInteger*)&value1);
const NSInteger b(*(NSInteger*)&value2);
return a == b;
}
};
const CFArrayCallBacks callbacks = {
.version = 0,
.retain = MONCallback::retain,
.release = MONCallback::release,
.copyDescription = MONCallback::copyDescription,
.equal = MONCallback::equal
};
const void** p((const void**)&vec.front());
NSArray * result((NSArray*)CFArrayCreate(0, p, vec.size(), &callbacks));
return [result autorelease];
}
void vec_demo() {
static_assert(sizeof(NSInteger) == sizeof(NSInteger*), "you can only use pointer-sized values in a CFArray");
std::vector<NSInteger> vec;
for (NSInteger i(0); i < 117; ++i) {
vec.push_back(i);
}
CFShow(NSIntegerVectorToNSArrayOfNSIntegers(vec));
}
Tuttavia, sarà necessario essere molto cauti per quanto riguarda l'utilizzo di questa collezione. La Fondazione si aspetta che gli elementi siano NSObject
s. Se lo passi in un'API esterna che si aspetta un array di NSObject
s, probabilmente causerà un errore (leggi: EXC_BAD_ACCESS
in objc_msgSend
).
Di solito, uno li converte in NSNumber
. Vorrei usare questo NSArray
di NSInteger
s nel mio programma solo se un'altra altra API era necessaria (Apple ne ha poche) - Semplicemente non giocano molto bene insieme.
In realtà intendevo "NSNumber" ma +1 per una risposta affascinante! – mydogisbox
NSArray non può contenere elementi del tipo primitivo NSInteger. –
@ RichardJ.RossIII in realtà, * può *. ho dimostrato esattamente questo nella mia risposta. – justin