0

I try to create double pointer to simulate two dimensions array to hold the ObjectiveC object

Here is my declare syntax: BlockInfo.m

@implement BlockInfo
-(void)someMethod{
}
@end

Other.m file

BlockInfo** pt = (BlockInfo**)malloc(sizeof(BlockInfo*)*10);

for(int i=0; i<10; i++){
        pt[i] = (BlockInfo*)malloc(sizeof(BlockInfo)*3);
}

Here are the errors:

Pointer point to non-const type 'BlockInfo*' with no explicit ownership

Application of 'sizeof' to interface 'BlockInfo*' is not supported on the architecture and platform

Any help would be appreciated!

elliptic00
  • 427
  • 4
  • 13
  • 1
    Have a look at the [Transitioning to ARC Release Notes](https://developer.apple.com/library/mac/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html), in particular the "Can I create a C array of retained pointers under ARC?" paragraph. – Martin R Sep 14 '15 at 09:48
  • 2
    Use `NSMutableArray`. – trojanfoe Sep 14 '15 at 10:44

2 Answers2

2

First of all you should really recheck whether you need ids 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;
}
Community
  • 1
  • 1
Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50
1

It seems that you tried to compile with ARC enabled. Try passing -fno-objc-arc as a compiler argument.

Please read the Objective-C Runtime Reference or the Objective-C Runtime source code for further details.

Michal
  • 15,429
  • 10
  • 73
  • 104
Mats
  • 8,528
  • 1
  • 29
  • 35
  • Thanks for quick reply, but all my code are ARC enabled so far. I'm wondering if there is way to enable ARC and use double pointer for ObjectiveC object? – elliptic00 Sep 14 '15 at 09:19
  • You can add command line options on a per file bases: https://developer.apple.com/library/mac/recipes/xcode_help-project_editor/Articles/Adding%20a%20Compiler%20Flag%20to%20a%20File.html – Mats Sep 14 '15 at 09:21