2017-01-21 15 views
2

Каков наилучший способ реализации метода для переноса массива C примитивных чисел в CFArray из CFNumbers?W примитивные значения C в CFArray из CFNumbers

Я хочу назвать что-то вроде:

double values[] = {1.2345, 678.9}; 
CFArrayRef arr = NumberWrappedValuesArray(&values, 2, kCFNumberDoubleType); 

И попытался это:

CFArrayRef NumberWrappedValuesArray(void * valueArrayPtr, CFIndex count, CFNumberType numberType) { 
    CFMutableArrayRef array = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks); 

    for (int i = 0; i < count; i++) { 
     CFNumberRef numberWrappedValue = CFNumberCreate(NULL, numberType, &valueArrayPtr[i]); 
     CFArrayAppendValue(array, numberWrappedValue); 
     CFRelease(numberWrappedValue); 
    } 

    CFRelease(array); 
    return array; 
} 
  1. Это не работает (возвращаемый массив имеет 0 элементов), почему и как это исправить Это?
  2. Есть ли более элегантный способ, потенциально избегая изменчивого CFArray?

Спасибо!

ответ

2

Вы можете использовать CFArrayCreate.

Пример:

CFArrayRef NumberWrappedValuesArray(void *valueArrayPtr, size_t size, CFIndex count, CFNumberType numberType) { 
    size_t i, n; 
    CFArrayRef ret; 
    CFNumberRef *ref = malloc(sizeof(CFNumberRef) * count); 

    /* create array of boxed types. */ 
    for (i = 0, n = count; i < n; ++i) 
     ref[i] = CFNumberCreate(NULL, numberType, ((char *)valueArrayPtr) + (size * i)); 

    /* create CFArray. */ 
    ret = CFArrayCreate(NULL, (const void **)ref, count, &kCFTypeArrayCallBacks); 

    /* release boxed types and malloc'ed array. */ 
    for (i = 0; i < n; ++i) 
     CFRelease(ref[i]); 
    free(ref); 

    /* return CFArray, without releasing first! Has to be done by the caller. */ 
    return ret; 
} 

Обработка ошибок опущены для ясности.

+0

Спасибо за ваш ответ! Это дает мне ошибку компилятора в CFArrayCreate(), что ref не является (const void **). Когда я его создаю, для первого примитивного числа в valueArrayPtr создается правильный CFNumber, но все следующие числа не имеют смысла (например, 3.474077185876084e-310 вместо 2.0). Есть идеи? – wolfrevo

+0

@wolfrevo Ожидается предупреждение о компиляторе. Я исправил его в примере. У меня нет ясной идеи, почему значения скремблированы, вы можете попробовать использовать «NULL» в качестве распределителя вместо значения по умолчанию. Я отредактировал приведенный выше пример. – Leandros

+1

Обязательно укажите эту функцию с помощью 'Create' в качестве первого слова, чтобы она подчинялась правилу Create. Вероятно, скремблированные числа, потому что это принимает 'void *', а не 'double *'. Это означает, что '[i]' продвигается на один байт за раз, а не на один двойной за раз, поэтому вы читаете части соседних чисел. Вы можете сделать это общее, но вы должны затем умножить 'i' на размер' CFNumberType' (вам придется сделать для этого 'switch', я не думаю, что есть' CFNumberTypeGetSize'). –