Objective-c syntax for 2d array instance variable

2019-08-06 04:05发布

问题:

Usually I treat instance variables in Objective-c like this:

@interface MyClass : NSObject
@property (nonatomic, retain) NSMutableArray *mutableArray;
@end

@implementation MyClass
@synthesize mutableArray;

- (id) init {
    if((self = [super init])) {
        self.mutableArray = [NSMutableArray array];
    }
    return self;
}

- (void) dealloc {
    [mutableArray release];
    [super dealloc];
}

@end

I feel pretty comfortable w/ the above syntax. However I'm not so comfortable w/ the syntax for a 2D array instance variable like NSUInteger 2dArray[10][10].

What's the appropriate Objective-c syntax for a 2d array instance variable with regards to interface declaration, synthesizing getters/setters and memory management?

回答1:

You don't need to allocate memory for your array; they are perfectly fine being defined in the class and they will always exist, at the same size. You therefore don't need to worry about memory management and your getter/setters should be defined manually, depending on what you want to do. For example these getter/setter methods allow getting/setting an individual value:

@interface MyClass : NSObject
{
    NSUInteger _twoDeeArray[10][10];
}

- (void)setTwoDeeArrayX:(NSUInteger)x y:(NSUInteger)y value:(NSUInteger)value;
- (NSUInteger)twoDeeArrayX:(NSUInteger)x y:(NSUInteger)y;

@end

@implementation MyClass

- (void)setTwoDeeArrayX:(NSUInteger)x y:(NSUInteger)y value:(NSUInteger)value
{
    _twoDeeArray[x][y] = value;
}

- (NSUInteger)twoDeeArrayX:(NSUInteger)x y:(NSUInteger)y
{
    return _twoDeeArray[x][y];
}

@end

You should probably have range-checking for x and y, but you get the idea.



回答2:

That's not an Objective C syntax. It's pure C syntax. You don't need to exclusively say that you want a 2D array of objc objects. Just declare/define the mutable array and add other arrays to it.



回答3:

For two-demensional arrays, you can:

  1. Go with C arrays (like what you mentioned in the post)
  2. Add NSMutableArray into NSMutableArray
  3. Create a class to implement your version of 2D-array

If you just want to use primitive types in your array, all three are good.

For Objective-C objects, you can also go with C array with id type but you have to manage memory allocation/deallocation yourself. 2 and 3 are better way to do this.

FYI:

  • 2D arrays using NSMutableArray
  • Creating a two dimensional array in Objective-C


回答4:

in iOS 6 you can use subscript to define a matrix class that uses the square bracket syntax matrix[row][col] where you can store objects and they are correctly retained by the matrix, differently than using a C array

First create a Row object, defined like this

- (id)initWithElementNumber:(NSUInteger)num {
    if (self = [super init]) {
        _row = [NSMutableArray arrayWithCapacity:num];
        for (int j = 0; j < num; j++)
            [_row addObject:[NSNull null]];
    }
    return self;
}

- (id)objectAtIndexedSubscript:(NSUInteger)idx {
    return self.row[idx];
}

- (void)setObject:(id)object atIndexedSubscript:(NSUInteger)idx {
    self.row[idx] = object;
}

@end

And then a Matrix class that uses the Row class previously defined:

@implementation UKMatrix

- (id)initWithRows:(NSUInteger)numRows columsn:(NSUInteger)numCol {
    if (self = [super init])
    {
        _numCol = numCol;
        _numRows = numRows;
        _rows = [NSMutableArray arrayWithCapacity:numRows];
        for (int j = 0; j < numRows; j++)
            [_rows addObject:[[UKRow alloc] initWithElementNumber:numCol]];
    }
    return self;
}

- (id)objectAtIndexedSubscript:(NSUInteger)idx {
    return self.rows[idx];
}

- (NSString *)description {
    NSString *matrixDesc = @"";
    for (int j = 0; j < self.numRows; j++) {
        matrixDesc = [matrixDesc stringByAppendingString:@"\n"];
        for (int k = 0; k < self.numCol; k++)
            matrixDesc = [matrixDesc stringByAppendingFormat:@" %@ ",self[j][k]];
    }
    return matrixDesc;
}

@end

then you can use the Matrix with the following syntax

UKMatrix *matrix = [[UKMatrix alloc] initWithRows:4 columsn:2];
matrix[1][1] = @2;
NSLog(@"%@", matrix);