Reputation: 171
Note: This question has been updated with suggestions supplied in answers below in which to bring a fuller context to the present state of the problem.
You may view complete project files here: https://github.com/cxx6xxc/Skeleton/blob/master/README.md
Conditions
I create an NSArray
in an object's init
method.
I return the NSArray with it's get method.
Problem
Upon arrival, the NSArray is null.
Attempt 1:
This is my original implementation.
- (id)init:
{
labels = [NSArray arrayWithObjects:@"Red", @"Green", @"Blue", nil];
return self;
}
Attempt 2:
Ismael suggested I wrap it with a sub-classing protocol.
neo suggested I retain the NSArray.
- (id)init:
{
self = [super init];
if (self)
{
labels = [NSArray arrayWithObjects:@"Red", @"Green", @"Blue", nil];
[labels retain];
}
return self;
}
Attempt 3:
Anoop Vaidya suggested I force ownership with alloc and NSMutableArray:
- (id)init:
{
self = [super init];
if (self)
{
labels = [[NSMutableArray alloc] initWithObjects:@"Red", @"Green", @"Blue", nil];
}
return self;
}
But, when I return the object, despite the different init suggestions cited above...
- (NSArray *)getLabels
{
return labels;
}
...with NSMutableArray...
- (NSMutableArray *)getLabels
{
return labels;
}
... the NSArray getter returns a null object.
int main(void)
{
id view;
view = [ZZView alloc];
id model;
model = [ZZModel alloc];
id controller;
controller = [[ZZController alloc] init: model: view];
labels = [[controller getModel] getLabels];
if(labels)
NSLog(@"allocated");
else
NSLog(@"not alloced");
[view dealloc];
[model dealloc];
[controller dealloc];
return EXIT_SUCCESS;
}
Question
What am I not doing, missing or what am I doing wrong that causes the null return value?
Upvotes: 2
Views: 312
Reputation: 171
The init method to model was never called, it is only allocated. Therefore, NSArrray labels doesn't exist, because it is created in the init method.
Upvotes: 0
Reputation: 3937
init
methods need to call some [super init], so you will need to do something like this:
- (id)init
{
self = [super init];
if (self) {
labels = [NSArray arrayWithObjects:@"Red", @"Green", @"Blue", nil];
}
return self;
}
Edit: looking at your git repo, I found
controller = [[ZZController alloc] init: model: view];
I'm not entirely sure how the compiler interprets the empty arguments, but my guess is that it reads them as nil, and therefore your ZZController doesn't have model
Also, you have some messy argument order, the first argument (with text init:
) is your model, and your second argument (with text model:
) is your view
(this according to your - (id)init: (ZZModel*)Model: (ZZView*)View
In order to make it work quickly, you should do
controller = [[ZZController alloc] init:model model:view];
I'm gonna take a (short) leap here and guess you are new to iOS development, so I'll recommend that you read about objc programming, how to write functions, how to send multiple parameters, so on and so forth, and after that, do some refactoring
Cheers!
Upvotes: 2
Reputation: 46543
You can do it in this way, hoping in .h you have NSMutableArray *labels;
:
- (id)init{
if (self = [super init]) {
labels = [[NSMutableArray alloc] initWithObjects:@"Red", @"Green", @"Blue", nil];
}
return self;
}
Upvotes: 0
Reputation: 1298
Assume you are not using ARC nor synthesising variable labels, you need to retain the array,
- (id)init:
{
labels = [NSArray arrayWithObjects:@"Red", @"Green", @"Blue", nil];
[labels retain];
return self;
}
Also, you need to release it when not using the array to prevent memory leakage.
Upvotes: 0
Reputation: 4044
I suggest you put a breakpoint in both your init and getLabels methods, and check the value of the instance variable that stores the array: you'll see which method does not behave as expected.
Upvotes: 0