Reputation: 2746
I have an NSMutableArray
of capacity 7. I want to put in each index a NSMutableArray
with capacity 6. In each of these 6 slots, I want the character A.
The other requirements are that I need to be able to access each index in each of the arrays. I previously had code like this
-(id)init{
self = [super init];
self.array = [[NSMutableArray alloc]initWithCapacity:7];
for (NSUInteger i = 0; i < self.board.count; i++) {
NSMutableArray *subArray = [[NSMutableArray alloc]init];
for (NSUInteger i = 0; i <subBoard.count; i++) {
[subArray addObject:@"A"];
}
[self.array insertObject:subArray atIndex:i];
}
return self;
}
The problem was that when I wanted to find an index in the subArray from access the main array, I'd have to do all sorts of casting and creating new variables to show that those pointers were NSMutableArrays.
Then I had this code
#import <Foundation/Foundation.h>
@interface NewArray : NSMutableArray
@property (strong, nonatomic) NSMutableArray *column1;
@property (strong, nonatomic) NSMutableArray *column2;
@property (strong, nonatomic) NSMutableArray *column3;
@property (strong, nonatomic) NSMutableArray *column4;
@property (strong, nonatomic) NSMutableArray *column5;
@property (strong, nonatomic) NSMutableArray *column6;
@property (strong, nonatomic) NSMutableArray *column7;
-(id)init
@end
But how do I write the init
method, so I don't have to do something like this
-(id)init{
self = [super init];
self = [[NSMutableArray alloc]initWithCapacity:7];
self.column1 = [[NSMutableArray alloc]initWithCapacity:6];
[self insertObject:self.column1 atIndex:0];
//etc. for each additional array to be added
return self;
}
Also, I'd have to add the character to each array separately. Seems really inefficient. I'd like to know if there is a smarter way.
Upvotes: 3
Views: 223
Reputation: 52538
First, never, ever even think about subclassing any of the basic classes like NSArray, NSMutableArray, NSString and so on. Apart from being an awfully bad idea in any language, it's especially bad in Objective-C because NSMutableArray for example is part of a class cluster and your chances of getting this to work properly are practically nil.
Second, there are times when you should use plain old C. Declare an object, derived from NSObject, and if you want a two-dimensional array of char, you give it a member char rowsColumns [7][6].
Upvotes: 1
Reputation: 8424
If you don't care about the capacity as explained here that it does make much of the difference. How about writing something like this
NSMutableArray *myArray = [@[
[@[@"A"] mutableCopy]
] mutableCopy];
myArray[0][0] = @"B";
Upvotes: 0
Reputation: 318804
Your first approach is much better than the second. But I'd made a few changes to make it better.
Start with the property:
@property (strong, nonatomic) NSMutableArray<NSMutableArray<NSString *> *> *columns;
This declares that you have a mutable array that contains mutable arrays that contain strings.
Then your init
method:
- (instancetype)init {
self = [super init];
if (self) {
_columns = [[NSMutableArray alloc] initWithCapacity:7];
// Just create one subarray filled with "A"
NSMutableArray<NSString *> *subArray = [[NSMutableArray alloc] initWithCapacity:6];
for (NSUInteger i = 0; i < 6; i++) {
[subArray addObject:@"A"];
}
// Now fill the main array with copies of the sub-array
for (NSUInteger i = 0; i < 7; i++) {
[_columns addObject:[subArray mutableCopy]];
}
}
return self;
}
Note that you referencing the count
property in the for
loop won't work. It starts out empty so count
will be zero and the loop won't execute.
Now you can access a specific value as simply as:
NSString *value = self.columns[4][3]; // read
self.columns[2][5] = @"Hello"; // write
Upvotes: 5