How to store C Arrays as a Property or iVar?
—Jens |
|
NSData.bytes is a property of type "void*". And NSPointerFunctions even has a property whose type is a C function pointer: @property (nullable) BOOL (*isEqualFunction)(const void *item1, const void*item2, NSUInteger (* _Nullable size)(const void *item)); ARC doesn't give a damn about C types, generally; it only pays attention to Obj-C references. The one C thing ARC will complain about is if you put an Obj-C reference type in a C struct, because there's no way to update the object's ref-count during the lifetime of the struct. (And that restriction goes away in C++ because ARC can add code to the constructor/destructor.)
—Jens |
|
Gary L. Wade
If you want an actual property encapsulating your C-based array, you could keep it within an NSMutableData object since it’s just bytes. I’m not sure if an NSData object would keep the actual data read-only (it’s certainly not growable), but it’s a VM-based optimization I’d expect to be a possible reason for not using NSData.
toggle quoted message
Show quoted text
-- Gary L. Wade
|
|
Dave
You could do that, but I’m doing millions of calculations on the elements of the Array, so it would be a lot slower and much more complex than needed……
toggle quoted message
Show quoted text
|
|
Dave
Well, you can’t use them as a property anyway, C Arrays *have* to be iVar’s, but I wrap a “Property Wrapper” around the iVars!
toggle quoted message
Show quoted text
|
|
Alex Zavatone
Is there a reason why he shouldn’t represent the values as NIntegers like I suggested before? I didn’t see a response to my suggestion explaining why it’s not a good idea.
toggle quoted message
Show quoted text
[myArray addObject:[NSNumber numberWithInt:myValue]]; [myArray addObject:@myValue]; [myArray addObject:@(myValue)];
|
|
Jeff Laing
Um, the headline says "How to store C Arrays as a Property ..." so at least one person (the original poster) has said this is about properties. My experience was that properties that are non-pointers work just fine, hence ints, reals, etc. but as soon as you start using pointers, the compiler starts squarking about ARC not liking those things. I can see you are advocating a struct containing a fixed-size array and that may well work for the original poster - but if the array had been dynamically allocated, then I think it would have failed, the difference being that the compiler can believe it knows how to clone a fixed-size array (memcpy) whereas it can't be confident about indirect memory. |
|
No one said this was a property. It's just an instance variable. Also, it's fine for properties to be C types — after all, there are plenty of integer or boolean properties, and UIKit and AppKit have properties whose types are structs like NSPoint and CGRect. I don't think a raw C array will work, since as mentioned before arrays aren't assignable in C, but a struct wrapping an array works fine. —Jens |
|
Jeff Laing
Can I ask if this discussion is academic or you have already tried? The reason I ask is that property values tend to need to support the NSObject protocol (ie, do the retain/release thing, whether manually or ARC) and I've always been given compilation failures whenever I try to start involving raw C memory management in that space. |
|
The time to read and unwrap an integer from an NSArray is probably under a microsecond, so it's unlikely to be a performance problem. But there's nothing wrong with using a C array. It's what I'd do, personally.
Yes, because the array will be smaller so it will take up less space in the CPU cache, causing fewer cache misses. But here the difference will be a few nanoseconds. —Jens |
|
Dave
Hi, It recurses through the cells in the Array and there could be around 7000 iterations, so I’d rather stick with normal integers. One thing I was going to ask is that, the value range on each cell is 0 to 10, at the moment its using an “int” to hold this (which I assume is 32 bits), would there be a speed impact if I made it int16 or int8? All the Best Dave
|
|
Dave
Hi, It recurses through the cells in the Array and there could be around 7000 iterations, so I’d rather stick with normal integers. One thing I was going to ask is that, the value range on each cell is 0 to 10, at the moment its using an “int” to hold this (which I assume is 32 bits), would there be a speed impact if I made it int16 or int8? All the Best Dave On
|
|
(IIRC you suggested using an NSMutableArray of NSNumbers?) Honestly, it depends. It does have overhead, although not as much as it used to, since NSNumbers of reasonable-size integers don't allocate any memory (they're just tagged pointers.) On the plus side, you get array bounds checking, and it's easy to grow the array dynamically if you ever need to. If you don't need high performance (e.g. you're not doing math-y stuff with these arrays) and you're not allocating millions of these, NSMutableArray is reasonable. Especially for those who aren't super comfortable with C. —Jens |
|
Dave
Hi Jens, You solved two problem in one with your last post - thanks a lot! I had some other information that was being passed back and forth and creating a structure allowed me to solve the Array copying problem and I could add the extra information fields to the struct! Thanks again, All the Best Dave
|
|
Alex Zavatone
In that light, is my suggestion useless overhead? |
|
You can't assign (or compare) arrays in C/C++. You have two options: (a) Call memcpy: memcpy(&myArray, &_mArray, sizeof(myArray)); (b) Wrap a struct around the array, since structs are copyable. Drawback is that you now have to refer to the array as a named field of the struct. typedef struct { int [10][10] a; } MyArrayType; MyArrayType myArray; … _mArray = myArray; (This is a pure C issue, so a book like K&R would be helpful.) —Jens |
|
Jack Brindle
Can you publish the actual declarations for myArray and mArray? The ones you show aren’t quite legal and
toggle quoted message
Show quoted text
will be rejected by C compilers. There isn’t that much different from regular C. In your code, you are not creating a property, but rather an instance variable. Thus it does not create anything named _mArray. If you created an @property var then the _mArray might work. Struct assignment does work in Objective C. I don’t remember that arrays may be copied, though. Might that be a C++ extension? - Jack On Aug 18, 2017, at 12:07 PM, Dave <dave@...> wrote: |
|
Pascal Bourguignon
Objective-C is C. You have to know C to be able to program in Objective-C. In C, arrays are not first class objects. So you cannot use = to copy arrays (or to take a reference to an array, there’s no such notion in C). The solution is to write a loop to copy the elements. void copy_my_array(int src[10][10],int dst[10][10]){ for(int i=0;i<10;++i){ for(int j=0;j<10;++j){ dst[i][j]=src[i][j];}}} then use: copy_my_array(myArray,_myArray); -- __Pascal J. Bourguignon__ |
|
Alex Zavatone
You can save them as NSIntegers in an NSMutableArray.
toggle quoted message
Show quoted text
The thing about NSDictionaries and NSArrays is that they need to contain NSObjects that are Cocoa Collections. Someone please correct me if I’m tragically misguided. But try that, Dave. Cheers, Alex Zavatone
|
|
Dave
Hi All,
I’ve converted some C code into Objective-C and have some C Array structures like so: int [10][10]) myArray; That I want to store in a Property or iVar inside a Wrapper Class. How do I do this? I’ve tried: @interface WrapperClass : NSObect { int [10][10]) mArray; } But I get an error if I try to assign or read it, as in: myArray = _mArray; or _mArray = myArray; Thanks a lot All the Best Dave |
|