NSMutableArray becomes empty when I call any IBAction - objective-c

Please help me i have a NSMutableArray which contains data until viewDidLoad is finished.
When I click any button I try to get the data in it and it just disappears.

If you created your array with a variant of [NSMutableArray array] it will be autoreleased. Assuming myArray is a property of your class, you should use
myArray = [[NSMutableArray] alloc] init]; //or initWithCapacity, etc.
If you still use reference counting, you need to add [myArray retain]; unless it is already retained in the #property declaration and release it in viewDidUnload:.

Related

I can't add my data object to my NSArray

So I have this method:
-(void)addLaneToRacingLanes:(UITapGestureRecognizer*)sender{
laneDataObject *data=[self.laneDataObjects objectAtIndex:sender.view.tag];
[self.racingLanes addObject:data];
NSLog(#"%i",self.racingLanes.count);
[sender.view setBackgroundColor:[UIColor yellowColor]];
}
It uses the tag from the senders view to find out which data object corresponds to that view.I'm using this to add to my racingLanes which is how I update these views, but my problem is that for some reason I cant add my laneDataObjects to my array racingLanes. Any ideas?
This is how the properties are set up:
#property (strong,nonatomic)NSArray *laneDataObjects;
#property (strong,nonatomic) NSMutableArray *racingLanes;
I have already run through the tags and they all work. The tags work such that lane 1 is tag 0 with its data object at 0, then lane 2 is tag 1 and its data is 1, so on and so forth. I already pre-tested this. And I have checked that both the laneDataObject array has been properly set up. Is it because my racingLanes isn't using a custom getter or setter? How would I go about changing that?
Incase it matters I used
NSLog(#" %i",self.racingLanes.count);
to find out if the array was empty.
It is a near certainty that the racingLanes has not been initialized: since the objects that you are adding are non-nil (you'd see an exception thrown otherwise) the racingLanes must be nil then.
You need to set racingLanes to NSMutableArray in the designated initializer:
_racingLanes = [NSMutableArray array];
Did you make sure to initialize your NSMutableArray in your class's -init or -viewDidLoad function?
// WITH ARC
self.racingLanes = [NSMutableArray array];
// WITHOUT ARC
self.racingLanes = [[NSMutableArray alloc] init];

unable to store an image in an NSMutableArray

I am trying to save an image in an NSMutable array and it is not working
here is what I am doing
[imagesList addObject:[UIImage imageNamed:#"b.png"]];
after executing this line I noticed that the number of objects remains 0
any reason ?
Thanks
I repeate this code in several areas :
Globally I declare :
NSMutableArray *imagesList;
NSUserDefaults *imagesHistory;
in my viewdidload method I write:
imagesHistory=[NSUserDefaults standardUserDefaults]; //imagesHistory is created globallt as NSUserDefault imagesHistory
[imagesHistory setObject:imagesList forKey:#"images history"];
UIImage *image;
image=[UIImage imageNamed:#"b.png"];
[imagesList addObject:image];
imagesHistory=[NSUserDefaults standardUserDefaults];
[imagesHistory setObject:imagesList forKey:#"images history"];
and in the didFinishLaunchingWithOptions I write : (even though I don t need to do it when I am adding strings ...)
imagesList = [[NSMutableArray alloc] init];
Regardless of whether it is a global variable or not, you still need to call alloc and init SOMEWHERE for the object. If you intend to use it throughout your app, then appDidFinishLaunchingWithOptions is a decent place to add this call:
imagesList = [[NSMutableArray alloc] init];
Is your empty array being retained? If you're not using Automatic Reference Counting, there's a good chance you're initializing the array with the following
imagesList = [[NSMutableArray alloc] init];
but it's not being retained. You'll want to retain the empty array so it gets appended to further on in your code.
imagesList = [[[NSMutableArray alloc] init] retain];
Just don't forget to release the array when you're all done with it, in viewDidUnload or wherever is appropriate.
You're allocating/initing imagesList AFTER you try to add an object. You need to alloc/init imageList before you add anything to it.
To make sure it's there, try something like this:
if (!imagelist) imageList = [[NSMutableArray alloc] init];
If it exists, and you're still having this problem, it's possible that you're allocating/initing a new NSMutableArray and assigning it to imageList after you've added the object. This means the old array would be discarded and you'd be left with a new array with zero items.
try UIImageView *image;
image=[UIImage imageNamed:#"b.png"];
also, in #property(nonatomic,retain) use 'strong' instead of 'retain'

Why Do I Have to Create An Object and Assign It to A Property in Objective C?

So I had this code, and it did not work:
for (NSDictionary *item in data){
[self.resultsArray addObject:item];
}
self.resultsArray is nil. But then I changed it to this:
NSMutableArray *myDataArray = [[NSMutableArray alloc] init];
for (NSDictionary *item in data){
[myDataArray addObject:item];
}
self.resultsArray = myDataArray;
[myDataArray release];
and now it worked. self.resultsArray is now populated
So I'm a beginner in Objective C and I was wondering why can I not just directly use it in the property's addObject. Why did I have to create another mutable array, populate it, assign it to the resultsArray property and release the mutable array I made?
Thanks in advance!
EDIT: Also, in a lot of books I've been working on, this is done a lot.
simple answer
You didn't initialize self.resultArray before adding objects to it. It is just a pointer to the value which is nil until you alloc it.
self.resultArray = [[NSMutableArray alloc] init]; before adding objects to it will solve the issue.
However, this way of alloc'ing will create a memory leak, therefore it is not shown in books and examples. Memory leak can happen if the self.resultArray property is marked as retain and by calling alloc it will be retained 2 times.
If self.resultsArray is nil, then [self.resultsArray addObject:item] will NOT add an object to the array, it will just do nothing (because the array will be nil by default, and sending messages to nil is a no-op in Objective-C). When you create a mutable array as a local variable, you can add things to it — then if you assign it to the property, well, everything works as you expect and self.resultsArray will no longer be nil.
Typically when you have properties like this, you'd set them up in your init method:
- (id)init {
// ...
self.resultsArray = [NSMutableArray array];
// or access the ivar directly:
// _resultsArray = [[NSMutableArray alloc] init];
// ...
}
Then as soon as your object is initialized you'll be able to add things to the array. Again, if you don't do this, it will be nil by default, and [self.resultsArray addObject:item] will have no effect.
Chances are you are not initializing the array (I'm going to assume myDataArray is an NSMutableArray).
In your init method, call myDataArray = [NSMutableArray array]; and it'll work
The important thing to note is that you're not creating another mutable array as you didn't have an array to start with. Merely declaring a property or variable does not create an object to go along with it. That's why self.resultsArray starts out as nil.
The working code you have is designed to allow you to explicitly release the array as you are retaining it twice: once when you alloc it and once when you assign it to your property. You only want one of those retains, so you release once.
You could just do:
self.resultsArray = [[NSMutableArray alloc] init];
[self.resultsArray release];
for (NSDictionary *item in data){
[self.resultsArray addObject:item];
}
This is less code, but it's not as clear. Clarity is important.

NSMutableArray vs NSArray

i have created a script, witch load the XML from server parse it an save it to NSMutableArray
[kategorienArray addObject:catName];
catName ist a String, if i NSLog the Array everything works fine.
After that i have created a tebleview, and reload Data
[kategorienAuswahl reloadData];
KategorienAuswahl is my TableView
and now a get the Problems
if i Use a "normal" array
NSArray *array = [[NSArray alloc] initWithObjects:#"iPhone", #"iPod", #"iPad",nil];
self.listData = array;
[array release];
the will be displayed, but if i use
cell.textLabel.text = [kategorienArray objectAtIndex:row];
i get EXC_BAD_ACCESS
instead it works fine with
cell.textLabel.text = [listData objectAtIndex:row];
I Add nwo
kategorienArray = [[NSMutableArray alloc] init];
kategorienArray = [NSMutableArray arrayWithCapacity:10];
but now i get no data in my Tableview
You might not have initialized your kategorienArray.
Do you have a kategorienArray = [[NSMutableArray alloc] init]; in your code? You should have done this before adding objects to it and then accessing them.
Also, make sure your array is retained at the point where it's created, so that the system doesn't reclaim its memory before you access its items. The way I use to make sure things are going right is to declare the mutable array as a property. In your viewcontroller's .h file put
#property (nonatomic, retain) NSMutableArray *kategorienArray;
and in your .m file put
#synthesize kategorienArray;
at the top and then
self.kategorienArray = [NSMutableArray array];
in viewDidLoad or somewhere, before adding items to it.
The problem may be that 'kategorienArray' has been (auto)released.
Is 'kategorienArray' an ivar ?
Check out if when you created the array you correctly retained it (particularly if you created it with a class method).

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.