Create an array of integers property in Objective-C

Objective CArraysProperties

Objective C Problem Overview


I'm having troubles creating a property of an array of integers in Objective-C. I'm not sure whether this is even possible to do in Obj-C so I'm hoping someone can help me in finding out either how to do it correctly or provide an alternative solution.

myclass.h

@interface myClass : NSObject {

@private int doubleDigits[10];
}

@property int doubleDigits;
@end

myclass.m

@implementation myClass

    @synthesize doubleDigits;
    -(id) init {
    	
    	self = [super init];
    	
    	int doubleDigits[10] = {1,2,3,4,5,6,7,8,9,10};
    	
    	return self;
    }
    
    @end

When I build and run, I get the following error:

> error: type of property 'doubleDigits' > does not match type of ivar > 'doubleDigits'

Objective C Solutions


Solution 1 - Objective C

This should work:

@interface MyClass
{
    int _doubleDigits[10]; 
}

@property(readonly) int *doubleDigits;

@end

@implementation MyClass

- (int *)doubleDigits
{
    return _doubleDigits;
}

@end

Solution 2 - Objective C

C arrays are not one of the supported data types for properties. See "The Objective-C Programming Language" in Xcode documentation, in the Declared Properties page:

> Supported Types > > You can declare a property for any > Objective-C class, Core Foundation > data type, or “plain old data” (POD) > type (see C++ Language Note: POD > Types). For constraints on using Core > Foundation types, however, see “Core > Foundation.”

POD does not include C arrays. See http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html

If you need an array, you should use NSArray or NSData.

The workarounds, as I see it, are like using (void *) to circumvent type checking. You can do it, but it makes your code less maintainable.

Solution 3 - Objective C

Like lucius said, it's not possible to have a C array property. Using an NSArray is the way to go. An array only stores objects, so you'd have to use NSNumbers to store your ints. With the new literal syntax, initialising it is very easy and straight-forward:

NSArray *doubleDigits = @[ @1, @2, @3, @4, @5, @6, @7, @8, @9, @10 ];

Or:

NSMutableArray *doubleDigits = [NSMutableArray array];

for (int n = 1; n <= 10; n++)
    [doubleDigits addObject:@(n)];

For more information: [NSArray Class Reference][1], [NSNumber Class Reference][2], [Literal Syntax][3]

[1]: http://developer.apple.com/library/ios/#documentation/cocoa/reference/foundation/Classes/NSArray_Class/NSArray.html/ "NSArray Class Reference" [2]: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/Reference/Reference.html/ "NSNumber Class Reference" [3]: http://joris.kluivers.nl/blog/2012/03/13/new-objectivec-literal-syntax/ "Objective-C Literal Syntax"

Solution 4 - Objective C

I'm just speculating:

I think that the variable defined in the ivars allocates the space right in the object. This prevents you from creating accessors because you can't give an array by value to a function but only through a pointer. Therefore you have to use a pointer in the ivars:

int *doubleDigits;

And then allocate the space for it in the init-method:

@synthesize doubleDigits;

- (id)init {
    if (self = [super init]) {
        doubleDigits = malloc(sizeof(int) * 10);
        /*
         * This works, but is dangerous (forbidden) because bufferDoubleDigits
         * gets deleted at the end of -(id)init because it's on the stack:
         * int bufferDoubleDigits[] = {1,2,3,4,5,6,7,8,9,10};
         * [self setDoubleDigits:bufferDoubleDigits];
         *
         * If you want to be on the safe side use memcpy() (needs #include <string.h>)
         * doubleDigits = malloc(sizeof(int) * 10);
         * int bufferDoubleDigits[] = {1,2,3,4,5,6,7,8,9,10};
         * memcpy(doubleDigits, bufferDoubleDigits, sizeof(int) * 10);
         */
    }
    return self;
}

- (void)dealloc {
    free(doubleDigits);
    [super dealloc];
}

In this case the interface looks like this:

@interface MyClass : NSObject {
    int *doubleDigits;
}
@property int *doubleDigits;

Edit:

I'm really unsure wether it's allowed to do this, are those values really on the stack or are they stored somewhere else? They are probably stored on the stack and therefore not safe to use in this context. (See the question on initializer lists)

int bufferDoubleDigits[] = {1,2,3,4,5,6,7,8,9,10};
[self setDoubleDigits:bufferDoubleDigits];

Solution 5 - Objective C

This works

@interface RGBComponents : NSObject {

    float components[8];

}

@property(readonly) float * components;

- (float *) components {
    return components;
}

Solution 6 - Objective C

You can put this in your .h file for your class and define it as property, in XCode 7:

@property int  (*stuffILike) [10];

Solution 7 - Objective C

I found all the previous answers too much complicated. I had the need to store an array of some ints as a property, and found the ObjC requirement of using a NSArray an unneeded complication of my software.

So I used this:

typedef struct my10ints {
    int arr[10];
} my10ints;

@interface myClasss : NSObject

@property my10ints doubleDigits;

@end

This compiles cleanly using Xcode 6.2.

My intention was to use it like this:

myClass obj;
obj.doubleDigits.arr[0] = 4;

HOWEVER, this does not work. This is what it produces:

int i = 4;
myClass obj;
obj.doubleDigits.arr[0] = i;
i = obj.doubleDigits.arr[0];
// i is now 0 !!!

The only way to use this correctly is:

int i = 4;
myClass obj;
my10ints ints;
ints = obj.doubleDigits;
ints.arr[0] = i;
obj.doubleDigits = ints;
i = obj.doubleDigits.arr[0];
// i is now 4

and so, defeats completely my point (avoiding the complication of using a NSArray).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjebcrumView Question on Stackoverflow
Solution 1 - Objective CrobottoborView Answer on Stackoverflow
Solution 2 - Objective CluciusView Answer on Stackoverflow
Solution 3 - Objective CTim VermeulenView Answer on Stackoverflow
Solution 4 - Objective CGeorg SchöllyView Answer on Stackoverflow
Solution 5 - Objective CMartin WestView Answer on Stackoverflow
Solution 6 - Objective CVladimir DespotovicView Answer on Stackoverflow
Solution 7 - Objective CgogView Answer on Stackoverflow