NSMutable Array won't alloc, remains nil - ios

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.

Related

NSMutableArray becomes immutable when reinstantiated?

I've made a NSMutableArray a property on my view controller, which holds some core data objects for users.
When the user presses a button , I clear out the contents of the mutable array with a while loop,
while (self.mArray.count != 0){
[context deleteObject:self.mArray[0]];
[self.mArray removeObjectAtIndex:0];
}
After the while loop, I reinit the array:
self.mArray = [[NSMutableArray alloc] init];
I know it isn't necessary since there should be zero objects left in the array, but regardless, when I reinitialize the array, and then check the class of the array in the debugger, I get __NSArrayI, which is corroborated by an exception thrown when I attempt to add an object into self.mArray right afterwards.
I've looked for any other references to my array, but I've always passed around [self.mArray mutableCopy] as arguments to other methods, and I never cast it as an NSArray. I just don't understand how calling [[NSMutableArray alloc] init] would initialize the array as an immutable array.
What am I missing?
It's likely that you have declared mArray as copy in the property declaration. Change that to strong.

iOS - NSMutableArray won't get filled

I basically have have a custon subclass of an UIViewController, which has a NSMutableArray called waypoints. I initialise it in the -(void)viewDidLoad method of the controller with
waypoints = [[NSMutableArray alloc] init];
Later, in a method which gets called via a presentedViewController with some parameters including a NSMutableDictionary as waypointData, I call
[waypoints insertObject:waypointData atIndex:0];
and I also tried
[waypoints addObject:waypointData];
But neither seems to work!
I logged some stuff there to make it more clear. The parameters get transmitted correctly and the NSMutableDictionary saved under waypointData is the correct content it should be. Logging the waypoints array before the insertion shows it empty (which is correct; app got launched; no data added yet) and after the insertion it's still empty. The log:
2014-02-19 14:40:11.050 xxx[xxx] waypoints before insertion: (null:)
2014-02-19 14:40:11.051 xxx[xxx] INSERT WAYPOINT
2014-02-19 14:40:11.052 xxx[xxx] waypoints after insertion: (null:)
INSERT WAYPOINT gets logged directly before the insertion, so the program routine is really executing the insertObject:atIndex: method.
TL;DR:
Even though insertObject:atIndex: (and -addObject:) for an NSMutableArray get called the object won't get inserted in the array.
EDIT:
This method gets called in -viewDidLoad too:
- (void)loadWaypoints {
id unarchivedObject = [NSKeyedUnarchiver unarchiveObjectWithFile:[[self applicationDocumentsDirectory] stringByAppendingString: kAppDataFilePlistName]];
waypoints = (NSMutableArray *)unarchivedObject;
}
unarchivedObject of course is NULL if there hasn't been anything saved yet. Thanks to 0x7fffffff.
Check your waypoints NSArray it shouldn't be nil when you call at [waypoints addObject:waypointData];
easiest way to make sure your 'waypoints' array isn't nil is doing this:
if (!waypoints)
{
waypoints = [NSMutableArray new];
}
[waypoints insertObject:waypointData atIndex:0];
or
if (!waypoints)
{
waypoints = [NSMutableArray new];
}
[waypoints addObject:waypointData];
It sounds like your waypoints array is nil. Post your header file, including the declaration of waypoints. Post your whole viewDidLoad method where you create the empty array.
The 2 most likely causes I can think of are that you declared waypoints as weak, or that you have a local variable waypoints in your viewDidLoad and you're creating an empty array in the local variable but not saving it to the instance variable.
Set a breakpoint in viewDidLoad at the line that creates the empty array. Step over it and make sure your array is being created. Then right-click on the variable down in the variables section of the debugger window and add a watchpoint to that variable. If it is getting cleared out then the breakpoint will cause your program to break at the offending line.
(My post assumes that you are using ARC. Are you?)
Please use following code:
if(waypoints == nil){
waypoints = [[NSMutableArray alloc] init];
}
[waypoints addObject:waypointData];

How to add strings to an NSMutableArray

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]];

Objective-c adding to array same instance with different properties

I'm trying the following code to create an instance, assign properties, add to array.
Then, assigning new properties and adding again.
However array will contain 2 identical objects (equal to the second one added). The class Message simply has several (nonatomic, retain) NSStrings/Integer properties.
This probably has something to do with my understanding of pointer, can someone explain?
self.messages=[[NSMutableArray alloc]init];
Message *m=[[Message alloc]init];
m.cb=#"2402";
m.ck=1001;
m.msg=#"as";
[self.messages addObject:m];
m.cb=#"2422";
m.ck=1002;
m.msg=#"aadfsdsdfdssdklsdflkh";
[self.messages addObject:m];
NSLog(#"%#",self.messages);
When you add an object to an array, it does not add a copy of the object to the array, but instead just a reference to it. If you want two different objects, then you need to create two different objects instead of re-using the same one (or, as #Brendon points out, create a copy when you add it to your array).
To fix your example, the most common technique would be to add the following line right before you start modifying the properties for the second object:
m=[[Message alloc]init];
Or, use a second pointer and object instead of reusing m.
EDIT:
To add a copy, change [self.messages addObject:m]; to [self.messages addObject:[m copy]];, assuming that the Message class conforms to the NSCopying protocol.
Yes, after executing the posted code self.messages contains the Message object twice, at indexes 0 and 1. That's not a problem, though. Arrays can contain any object, even themselves.
It seems that you want two distict objects, so you would just create a second Message.
You can either implement the NSCopy protocol — as mentioned by lnafziger — or just create new instances quite easily in a for loop.
«Two or more, use a for»
— Edsger W. Dijkstra
self.messages=[[NSMutableArray alloc] init];
NSArray *dataArray = #[ #{#"cb": #"2402", #"ck": #(1001), #"msg": #"as"},
#{#"cb": #"2422", #"ck": #(1002), #"msg": #"aadfsdsdfdssdklsdflkh"}
];
for(NSDictionary *data in dataArray) {
Message *m=[[Message alloc] init];
m.cb = data[#"cb"];
m.ck = [data[#"ck"] integerValue];
m.msg = data[#"msg"];
[self.messages addObject:m];
}

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