Can't add to an NSMutableArray with addObject method - objective-c

I am having an issue with the addObject method of an NSMutableArrayObject. Here's the code I'm using right now:
- (void)addBirdSightingWithName:(NSString *)name location:(NSString *)location {
BirdSighting *bird;
NSDate *today = [NSDate date];
bird = [[BirdSighting alloc] initWithName:name location:location date:today];
[self.masterBirdSightingList addObject:bird];
NSLog(#"Elements: %d", [self.masterBirdSightingList count]);
}
When this code runs, the NSLog call prints the value 0 to the console. I don't know what could be causing this.
EDIT:
I have looked deeper into the code, and I have discovered that the problem is that my BirdSightingDataController is never initialized. Now my question is: Where can I place the init for my BirdSightingDataController? In the viewDidLoad?
Thanks to everyone for the help.

Did you allocate memory to masterBirdSightingList?
self.masterBirdSightingList = [[NSMutableArray alloc] init];

In almost every case where cellForRowAtIndexPath: is not called is because numberOfRowsInSection: returns 0.
Place a log there and make sure you return more than one item and you should be able to see your cells. If you need further help please post the code in your:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

Check your property accessor. Are you sure it's returning the correct object? Make sure the name of the property matches the instance variable or you've specified it correctly (For example: #synthesize masterBirdSightingList = _masterBirdSightingList;. If the property accessor doesn't match the iVar, it will return nil. Of course, if you're manually implementing the accessor check your code there. If you're not, you could also try manually implementing it to make sure.
To do a quick check, remove the self.masterBirdSightingList and replace it with masterBirdSightingList (assuming that's the iVar name) to access the iVar directly and see what happens.

Related

Adding and getting values of NSMutableDictionary not working [duplicate]

This question already has an answer here:
NSMutableDictionary setObject:forKey: fails to add key
(1 answer)
Closed 8 years ago.
I'm trying to do some complex stuff, but when I add to an nsmutabledictionary and try to get values from it, it's simply returning nothing and not printing anything when I try to print what it returns. I can't even get the following to print anything in an ibaction, even though the action is being triggered. Could you like me know if I'm doing anything wrong and what it is? Thanks!
Sample code of super simplified version of what I'm doing:
NSMutableDictionary *test;
[test setObject:#"ValueIWantToGet" forKey:#"KeyIAmSetting"];
NSLog([test objectForKey:#"KeyIAmSetting"]); //Should print "ValueIWantToGet", right?
Your test variable is not initialized. Do this instead:
NSMutableDictionary *test = [NSMutableDictionary dictionary];
or
NSMutableDictionary *test = [[NSMutableDictionary alloc] init];
In Objective-C all objects are manipulated through pointers. Hence the asterisks in declarations in front of variable names. When you do not assign anything to a pointer, its value remains uninitialized, so any reference to it is undefined behavior. In situations when the value happens to be nil, however, you would not see a crash, because Objective-C allows sending messages to nil (they have no effect).
I'm making a property of an NSMutableDictionary, so how should I initialized it if it's a property?
Properties should be initialized in the initializer of your class, for example
-(instancetype)init {
if (self = [super init]) {
_test = [NSMutableDictionary dictionary];
}
return self;
}

Cannot add items to an NSMutableArray ivar

My goal is to add a string to array, and I do that in a method which I call.
In this method, I get a null value in the array, and don't know why. I have this at the start of my class:
NSMutableArray *listOfEvents;
and a method which I call on each event:
-(void)EventList
{
[listOfEvents addObject:#"ran"];
NSLog(#"%#", listOfEvents);
}
I get (null) in the log.
If I put the array definition NSMutableArray *listOfEvents; in the function body, I get the string value #"ran", each time, so the array always has only one value, instead of having many strings named #"ran".
What's wrong with this? It seems that I can't understand something about arrays, even though I have read the documents a number of times.
I'm assuming you haven't initialized listOfEvents.
Make sure you do listOfEvents = [[NSMutableArray alloc] init]; in your class's init method. Also make sure you release it in your class's dealloc method.
If you're getting nil in your log message, you need to make sure listOfEvents is non-nil before adding your object. IE:
-(void)EventList
{
if (listOfEvents == nil) {
listOfEvents = [[NSMutableArray alloc] init];
}
[listOfEvents addObject:#"ran"];
NSLog(#"%#",listOfEvents);
}
In Objective-C, messages with void return types sent to nil go to absolutely-silent nowhere-land.
Also, for the sake of balance, be sure you have a [listOfEvents release] call in your dealloc implementation.
Apparently you're not initializing your array.
NSMutableArray *listOfEvents = [[NSMutableArray alloc] init];
If that's your problem, I suggest reading the docs again. And not the NSMutableArray docs. Go back to The Objective-C Programming Language and others.
You need to alloc the NSMutableArray. Try doing this first -
NSMutableArray *listOfEvents = [[NSMutableArray alloc] init];
After this you could do what you what you planned...

Method works correctly when called from within its class but not otherwise

I wrote this function in my RootViewController. appRecord is an object holding an XML attribute.
- (NSString*) getString:(int)row{
AppRecord *appRecord = [self.entries objectAtIndex:row];
NSString *appName = appRecord.appName;
return appName;
}
I want to use this function again by writing this:
RootViewController *record = [RootViewController new];
NSString *appsName = [record getString:0];
NSLOG(appsName);
After I compiled, it didn't return anything, but it works and returns appsName if I use this function inside the RootViewController class ([self getString:0]), so I know there is no problem with the function. When I tried to change return appName to return #"test", it worked and returned something when I accessed it from the other class.
This means there is a problem with this appRecord; it was returned inside the class but returns nothing when I access it from another class.
How to solve this problem?
You are getting your AppRecord from self.entries in the instance of RootViewController record. This means unless your new initializer initializes and populates its entries variable (array by the looks of things) before you call getString:, it won't be able to return anything since that array is empty.
Beyond that, I don't know if you want your getString:(int) method to access a different array, or if the problem is in your initialization of RootViewController (more likely)
Maybe I don't understand your question, but if you are relying on the NSLog statement to see if the function is returning anything, you should change it to:
NSLog(#"%#", appsname);

big memory problem in objective c

i've a function like this:
#property(nonatomic,retain) NSMutableArray *array;
#synthesize array = _array;
(NSMutableArray *) name
{
self.array = [[NSMutableArray alloc]init];
[_array addObject:object];
[object release];
return [_array autorelase];
}
In the other function i've a property like the property above, named result, and i make:
self.result = [... name];
Then in dealloc i make
[_result release];
and it crashes in this point, how can i solve this?
I've tried many roads, but or it crashes, or i see memory leak in Instruments, where am i wronging?
Thanks.
While there's a lot wrong with this code, the likely cause of your crash is that you're releasing object within -name without taking ownership of it- unless you're creating object within the method through a call to -alloc, -new, or -copy, that method doesn't own it and isn't responsible for releasing it. This is causing that object to be invalid within the NSMutableArray, so when _result releases, it attempts to release an invalid piece of memory and crashes.
Also, properties aren't simply local variables for individual functions, they're member variables for instances of the class for which you're writing these classes. If your end goal is only to return an autoreleased array and set it to result you could do the following:
- (NSMutableArray *) name {
//call a convenience method- it comes back autoreleased
NSMutableArray* theArray = [NSMutableArray array];
[theArray addObject:object];
//don't release object unless you took ownership of it in this function
return theArray;
}
then outside the function, either call self.result = [... name] or [self setResult:[... name]];
You have a very strange method definition (the header should have a - before the return type), and inside that definition you are accessing a variable called object that doesn't seem to exist. I'm not sure what you want, but you've got at least one memory problem. The array that you create in name gets leaked every time the method is called. If you add some details, like the crash message, someone may be able to help more.

simple NSMutable array question

umm So simple question here:
I have an instance of NSMutableArray declared in my header
NSMutableArray *day19;
#property (nonatomic, retain) NSMutableArray *day19
implementation:
#synthesize day19;
In my viewDidLoad
self.day19 = [[NSMutableArray alloc] init];
In the myMethod where I want to add objects to the array I:
NSObject *newObject = [[NSObject alloc] init];
[day19 addObject:newObject];
However... when i check the day19 array there is nothing in it. If I conversely add the newObject to a tempArray within the myMethod scope and then set the day19 array to the tempArray, day19 has the objects.
Super basic I know just must be a confused morning or something...
thanks for any help
Is day19 actually an instance variable? In the snippet, it's not clear when it's declared as an instance variable or just as a variable outside the scope of the class.
A couple of things:
Are you sure viewDidLoad is the right place to init your array? Confer here.
Also, at least from the code you've got posted, it looks like you're being sloppy with your retains. If your property is a retain type, you should not be writing:
self.myProperty = [[Something alloc] init]; // double retain here, bad
You should instead be writing something like:
self.myProperty = [[[Something alloc] init] autorelease]; // single, good
Also, with
NSObject *newObject = [[NSObject alloc] init];
[day19 addObject:newObject];
unless you have a
[newObject release];
down the pike, you've got a memory leak.
In my viewDidLoad
self.day19 = [[NSMutableArray alloc] init];
In the myMethod where I want to add objects to the array I:
NSObject *newObject = [[NSObject alloc] init];
[day19 addObject:newObject];
However... when i check the day19 array there is nothing in it. If I conversely add the newObject to a tempArray within the myMethod scope and then set the day19 array to the tempArray, day19 has the objects.
Let me guess: You checked the array with code like this:
NSLog(#"day19 contains %lu objects", [day19 count]);
Remember that a message to nil does nothing and returns nil, 0, or 0.0. That's why the output said 0 objects: You don't have an array in the first place. The most probable reason for that is that viewDidLoad hasn't been called yet, so you have not yet created the mutable array.
It's also possible that you have an array (i.e., the view has been loaded) at the time you examine the array, but you didn't have an array yet (the view hadn't been loaded yet) at the time you tried to add to the array, so your addObject: message fell on deaf ears.
Consider creating the array earlier. You probably should be creating it in init or initWithCoder:.
A third possibility is that you examined the array before you ever added to it. Make sure you log or break at both points, so you know which one happened first.
Whatever the problem is, you also need to either assign the array to the instance variable, not the property, or autorelease the array before assigning it to the property. Otherwise, you're over-retaining the array, which means you will probably leak it later on. You probably need to review the Memory Management Programming Guide for Cocoa.