How to add strings to an NSMutableArray - ios

I am trying to select multiple UITableViewCells, it is working fine, but I can't add strings to my NSMutableArray.
I am using this code, and my log always is (null):
self.mutarray = [[NSMutableArray alloc] init];
[self.mutarray addObject:path]; //path is an NSString
NSLog(#"%#", self.mutarray);
It must add the path of the UITableViewCell to the NSMutableArray, is that even possible?
Oh, and I am calling this in - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

As per your comments "it shows only the new added string, but not all strings.". This is because you are allocating NSMutable Array in the delegate method of table view. Everytime you hit the cell a new array is get allocated.
Either allocate your "mutarray" array in ViewDidLoad
Or
Only allocate it if it is nil or empty.
if(!self.mutarray)
self.mutarray = [[NSMutableArray alloc] init];

It seems that you haven't initialized your array. A good practice for properties is using something called lazy initialization.
Add this method.
- (NSMutableArray *)mutarray
{
if (!_mutarray) {
_mutarray = [[NSMutableArray alloc] init];
}
return _mutarray;
}
So every time you request the array, the accessor will make sure that the object is created before returning it. This is a good way of defensive programming.

You have to alloc/init before adding any objects:
if(!mutarray)mutarray = [[NSMutableArray alloc]init];
[self.mutarray addObject:path];

Have you tried to add a copy of the path?
Since UITableViewCells are resused, maybe the problem resides to this?
[self.mutarray addObject:[path copy]];

Related

How to add an object to array?

I'm using an NSMutableArray to populate cells in my tableview. The problem is, when I try adding an object to my array, it replaces all the objects with the one that was added so I always only have 1 object in my array. Because of this, my tableview always has one cell that is just overwritten whenever the below method is called. Am I missing something?
_selectedThingArray = [[NSMutableArray alloc] init];
_currentThing = newThing;
//Note: newThing is the object being passed when this method is called.
//It is the new data that will should passed into the cell.
[_selectedThingArray addObject:_currentThing];
NSLog(#"%#", newThing);
NSLog(#"array: %#", _selectedThingArray);
[self.tableView reloadData];
Is this line:
_selectedThingArray = [[NSMutableArray alloc] init];
executed every time you "try adding an object"? If yes, then this is your problem. Instead of adding an object to an existing array, you replace it with a brand new array and add object to this new array.
You need to either create the array at some point before you “try adding an object”, or create the array in the same place you're doing it now, but only when you have not already created one.
Add this if condition before allocation:
if(!_selectedThingArray)
_selectedThingArray = [[NSMutableArray alloc] init];
Instead of this only:
_selectedThingArray = [[NSMutableArray alloc] init];
Everything will be fixed.

NSMutable Array won't alloc, remains nil

A XML parser is trying to alloc its delegate's NSMutable array called masterCodeList. From the following code, you'll see that this fails. (I am a total newbie.)
if (dataController.masterCodeList == nil){
dataController.masterCodeList =[[NSMutableArray alloc] init];
if (dataController.masterCodeList == nil) {
NSLog(#"the init of the mutable array did NOT work");
}
}
I get the the init of the mutable array did NOT work message every time. I am importing the dataController header.
#import "CodeDataController.h"
I am getting no other error message, the parser is parsing fine and the app is running smoothly without content.
Thanks in advance.
What does your declaration of masterCodeList look like?
Is it a property, and is it synthesized, or are you making your own setter/getter?
An alternative would be to try using an intermediate placeholder, ie:
NSMutableArray *temp = [[NSMutableArray alloc] init];
[dataController setMasterCodeList:temp];
and see if that sets your array correctly.
(note: that code may or may not have leaks)
could you post your implementation of the dataController object in this class, and its attributes from the other class?
you also may want to try using the isEqual method instead of == nil.

iOS Memory Leak Advice

I'm pretty sure this is causing a leak and I would like some advice. Here's code based on what I'm doing:
NSMutableArray* straVideoTitles;
- (void) parseData{
//stuff
straVideoTitles = [self getVideoTitle:strData]; //strData contains unparsed data
//more stuff
}
- (NSMutableArray*) getVideoTitles:(NSString*)strData{
NSMutableArray *array;
array = [[NSMutableArray alloc] init];
//Parse data and populate array
return array;
}
Based on the fact that I'm allocating space for NSMutableArray and not releasing it, thats a leak right? How do I tackle this? Should I forgo returning a value and assign straVideoTitles inside getVideoTitles then release like:
- (void) getVideoTitles:(NSString*)strData{
NSMutableArray *array;
array = [[NSMutableArray alloc] init];
//Parse data and populate array
straVideoTitles = array;
[array release];
}
or am i going about this all wrong? Or is everything fine because I'm releasing straVideoTitles in dalloc?
You could change the
return array;
into
return [array autorelease];
Or you could use ARC and just don't care about it anymore.
Edit: The second approach is possible and does not include a memory leak but the code is less capsulated and therefore less reusable and future prove.
Change to
return [array autorelease];
It is good practice to return autorelease objects from methods. This is called a deferred release message.
You are relinquishing ownership while allowing the caller of the method to use the returned array before it is deallocated.
Your return statement should read:
return [array autorelease];
For more information on memory management take a look here:
Advanced Memory Management Programming Guide

Setting NSDictionary object as a property in child view either leaks when not released or gives EXC_BAD_ACCESS error when released

I have the following problem: In a certain view controller I have a NSDictionary, which itself is an entree in an NSArray object. This view controller has a child view which displays some of the key value pairs that are in this dictionary. Since I need only some key value pairs, I construct a new dictionary object from which I then remove the key value pair I do not want to have in it. To be able to access this dictionary in the child view, I though it would be possible to just set the dictionary via a property, which seems to work fine. To illustrate with some code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
...
// today is an instance of NSArray holding a number of NSDictionary objects
NSDictionary *completeData = [self.today objectAtIndex:row];
NSDictionary *data = [[NSDictionary alloc] initWithDictionary:completeData];
[data removeObjectForKey:#"name"];
SomeViewController *childController = [[SomeViewController alloc] init];
childController.data = data;
[self.navigationController pushViewController:childController animated:YES];
[childController release];
// This results in a EXC_BAD_ACCESS error when navigating back to the parent
// view and calling didSelectRowAtIndexPath a second time. When commenting this
// line out, the error dissapears, but now the object leaks
[data release];
}
The problem arises when, after returning to the parent view, I try to replace the NSArray object (today) by an updated version of itself by calling
- (void)refreshDataNotification:(NSNotification *)notification {
if (notification) {
self.today = [NSArray arrayWithArray:[[[MyAppDelegate getAppDelegate] todaySchedule]
objectForKey:#"data"]];
[self.tableView reloadData];
}
}
Note that as long as I do not release 'data' in didSelectRowAtIndexPath I get no error, but then the object leaks. When I do release it, I receive an EXC_BAD_ACCESS when refreshDataNotification is executed.
If someone has any clue as to what I might be doing wrong, then please do share with me.
Set the environment variable NSZombieEnabled to YES to get more helpful error messages about over releasing objects. (Set the environment variable by viewing details under 'Executables')
Also, it would be helpful to see how you've defined your properties. (e.g. what is the #property for data in SomeViewController?)
ps - I know you haven't pasted actual code, but data is a terrible instance name for an NSDictionary. dict is better - but something more descriptive would make your code easier to understand.

Obj - C: Having trouble creating a UITableView that updates cells from an HTTP API in real-time (one at a time)

I am polling an HTTP API - it returns one item at a time, in real-time (about every 4 seconds). As each item is received, I would like a new UITableView cell to be populated. The full list of received items must remain in a class property, I'm guessing an NSMutableArray. What is the best way to initialize an NSMutableArray as a class property, update it as new information comes in, and then use the count to update a new UITableViewCell?
Here's how I'm adding content to an NSMutableDictionary:
NSMutableDictionary *messageContents = [[NSMutableDictionary alloc] init];
[messageContents retain];
[messageContents setValue:messageText forKey:#"text"];
[messageContents setValue:image forKey:#"image"];
[self addMessageToDataArray:messageContents];
Here's the method stuffing objects into the array:
- (void)addMessageToDataArray:(NSArray *)messageDictionary {
[self.messageDataArray addObject:messageDictionary];
NSLog(#"count = %#", [self.messageDataArray count]);
[self reloadTableData];
}
At this point, calling count on the messageDataArray class property crashes the application. I'm very used to working with arrays in Actionscript, Obj-C is obviously totally different. Please explain the method for instantiating an NSMutableArray as a class property, filling it with NSMutableDictionary's and then finding the NSMutableArray count (which will be dynamically updating in real-time) so I can use that info to update a UITableView (on the fly).
Or... tell me I'm being silly and suggest a much easier solution.
From your description I would guess you're not allocating the messageDataArray before using it.
The init function for your table view (controller?) class should have a line like this
messageDataArray = [[NSMutableArray alloc] initWithCapacity:20];
It's also worth checking that you have [messageDataArray release]; in your dealloc method.

Resources