views:

63

answers:

3

I'm new to obj-c and I'm used to creating a property declaration for all my member vars and synthesizing them, just got the hang of it in fact. Along comes a need for a simple C array of a struct I typedeffed myself (I guess the struct aspect doesn't really matter).

Can someone explain what I should be doing with this C array as far as property declarations? Should I not be using a property declaration at all?

I tried memsetting the memory in the array, as well, and failed miserably with a compile error. Can someone explain that as well?

A: 

You certainly can treat the array as a property, it will have "assign" behaviour because you can't retain a struct. Essentially you're still totally responsible for the memory allocation of the array.

Another option you have is to replace your struct with an object. Then it works more naturally with the property machinery, and opens up the Foundation collection classes like NSArray to you.

Graham Lee
I was a little uncertain about using NSArray (which was my initial approach). I just wanted to do some simple direct access to array elements just as in C, but was unsure if I could simply allocate an NSArray and access element 16, for instance, and write into and read out of it, or if there was some different behavior with them than C arrays that didn't allow this. Thinking back on it, though, I guess I should have figured it will behave just as C arrays do in terms of being able to access random elements and set/get their values without needing to fill lower index elements.
Joey
Also, I'm having some issues trying to set it as a property. If I have MyStruct mList[5]; as my member var, I cannot do @property (nonatomic, assign) MyStruct mList[5]; because I get a Bad Property Declaration compile error.
Joey
@Joey: I think you'll need to define the property as `@property (nonatomic, assign) MyStruct *mList;` to use it as a C array. And in the case of `NSArray`, you must fill in elements 0-7 before you can use element 8. You can use the object `[NSNull null]` to act as a placeholder for unset values.
Graham Lee
You actually can't meaningfully use a C array as a writable property, since an array is not something to which you can assign.
Chuck
+1  A: 

This answer doesn't really solve your problem, it just explains why your approach didn't work.

In C you cannot return array types from functions. This is simply a limitation of the language (intentional or unintentional I don't know). By extension, in Objective-C you cannot return array types from methods. This also means that you can't use array types as properties, because the compiler is unable to synthesize a method that returns an array type.

C arrays are automatically converted into pointer types when used in an expression, so you can follow @Graham's advice and use pointers instead. The downside to this approach is that you must know exactly how many elements are in the array so that you don't accidentally read past the end of the it. If the number of elements is fixed and known at compile-time, this is probably the way to go (if you want to avoid NSArray for whatever reason).

It's difficult to answer whymemset failed to compile without actually seeing how you used it, but generally speaking this is how it can be used:

MyStruct someStructs[10];

memset(someStructs, 0, sizeof someStructs);

Alternatively, it is possible to return structs from functions/methods, even if they contain arrays. Theoretically speaking, you could create a struct containing an array of MyStruct and use this new struct type as the property type. Practically speaking this isn't a good idea since it just adds a layer of complexity.

dreamlax
You can read/write past the end of an array-syntax array, too. The following is legal, though broken, C: int x[2] = {0}; x[27] = 3;
Graham Lee
+1  A: 

If you have this:

@interface MyClass
{
    struct MyStruct foo[5];
}
@end

you can't have a read/write property at all. You can declare a read only property

@property (readonly, assign) struct MyStruct* fooProperty;

which will give you a pointer to the array. However, this is probably bad since it gives the rest of your code internal access to the structure of MyClass. It's proably better to implement the KVC indexed accessors, which you'll have to do manually.

JeremyP