First of all you should really recheck whether you need id
s in a C array. You have done it? Okay, do it again. You still need it? Okay, go on reading.
1.
What's wrong in your code is that you try to allocate the instance with malloc()
. Never do that. Use +alloc-init
, use +new
, use a convenience allocator, but always use the framework for instance creation. Beside the fact that you give the RTE the chance to register instance creation, it is easier to you, because otherwise you have to set up the proper infrastructure of the instance. And there is no reason to do instance creation via C's malloc()
.
2.
Beside this you can store instance references (expressions of type id
) to C objects ("variables"). To be more precise: You do that all the time, because every reference to an instance is a C object ("variable"). Therefore you can use C arrays, too.
A type is a retainable object owner type if it is a retainable object pointer type or an array type whose element type is a retainable object owner type.
http://clang.llvm.org/docs/AutomaticReferenceCounting.html#id20
The reason for this is that C does not allow copying the whole array (as with structs), so you have to assign every single reference, what you do in your code.
But there are some caveats:
ARC cannot really follow the instance's ownership, when the array loses its extent. So set every element to nil
explicitly, before the extent of the array is lost.
Do not use memcpy()
or a similar function to change values of the elements. ARC has no chance to release the reference stored before or to retain the newly stored instance.
When you assign a new reference to an element, the old one is released. Therefore at the very beginning you have to fill the whole array with nil
. (For local variables this is done automatically. That's the reason, why strong local vars are initialized.) calloc()
does this automatically for you.
Typically the elements shall be strong references. You have to specify this explicitly.
BTW: Stylistic: You can malloc an C array of type id*
, because all object references has equal size. (And has to, obviously). You shouldn't cast a malloc()
's return value.
So something like this should work:
__strong BlockInfo** pt = calloc(10, sizeof(id));
for(int i=0; i<10; i++){
pt[i] = [BlockInfo new];
}
…
for(int i=0; i<10; i++){
pt[i] = nil;
}