0

我创建了一个这样的 C 数组:

unsigned char colorComps[] = {2, 3, 22,   55, 9, 1};

我想将其传递给 Objective-C 对象的初始化程序。

所以我想我必须把数组放在堆上:

size_t arrayByteSize = numColorCompVals * sizeof(unsigned char);
unsigned char *colorCompsHeap = (unsigned char*)malloc(arrayByteSize);

然后我必须将我的第一个“堆栈内存数组”写入 for 循环中的堆数组:

for (int i = 0; i < numColorCompVals; i++) {
   colorCompsHeap[i] = colorComps[i];
}

附带问题:是否有更优雅的解决方案来避免 for 循环步骤?

然后我将它传递给方法:

定义为

- (id)initWithColorCompsC:(unsigned char *)colorCompsHeap;

TheObject *obj = [[TheObject alloc] initWithColorCompsC:colorCompsHeap];

TheObject具有保存 C 数组的属性:

@property (nonatomic, assign) unsigned char *colorComps;

在 -dealloc 我释放它:

free(_colorComps);

这是理论上的。我将 ARC 用于 Objective-C。我这样做是正确的还是有更好的方法?

4

3 回答 3

2

这似乎很好,但是......

  1. 不要转换malloc();的返回值
  2. 并且不要重新发明memcpy()。而不是你的 for 循环,写memcpy(dest, src, size).
于 2013-08-07T14:02:47.870 回答
1

如果TheObject要释放数组,那么它的init方法应该是制作副本的方法,而不是调用者。这样,每个实例都TheObject制作自己的副本并释放自己的副本,它拥有该副本。

此外,init 的参数来自哪里,堆栈或堆也无关紧要。该init方法是否复制它并不重要。

使用 memcpy 制作带有sizeof目标数组的副本,对于 .m 文件如下所示:

@interface PTTEST ()
@property (nonatomic, assign) unsigned char *colorComps;
@end

@implementation PTTEST

- (void)dealloc
{
    free(_colorComps);
}

- (id)initWithColorCompsC:(unsigned char *)colorComps
       numberOfColorComps:(unsigned)numberOfColorComps
{
    self = [super init];
    if (self) {
        // compute size based on sizeof the first element (in case
        // the element type get changed later, this still works right)
        size_t arraySize = sizeof(colorComps[0]) * numberOfColorComps;

        _colorComps = malloc(arraySize);

        memcpy(_colorComps, colorComps, arraySize);
    }
    return self;
}

@end
于 2013-08-07T15:39:12.343 回答
0

对我来说似乎不正确,你正在用(一个双精度数组colorCompsHeap)的值填充(一个无符号字符colorComps[]数组)

unsigned char u = 0.2;

printf("%f\n", (double)u);

输出0.000000

于 2013-08-07T14:10:47.907 回答