add new object to nsmutablearray replace all objects in array - ios

i try to add new object to my nsmutablearray but every time it replace all object
-(void)addToStack:(Coordinate *)coord{
Coordinate*c = [[Coordinate alloc] init];
c.x=coord.x;
c.y = coord.y;
if (coord.x==0 && coord.y==0) {
c.x=coord.x+1;
[_stack addObject:c];
c.x=coord.x;
c.y=coord.y+1;
[_stack addObject:c];
c.y=coord.y;
}
}

You are not adding a new object but you are changing the old object where the reference will remain the same.
NSMutableArray addObject will not add it because it already exists in the array.
So, when trying to add a new object, first create a copy of the one that you want to change, like this:
Coordinate *newCoordinate = [Coordinate mutableCopy];
// change attributes
// add it to the array

Everybody who said that adding the same object twice deletes the first instance and replaces it, is wrong.
Arrays can contain duplicate references to the same object. However, it's more like saving the same street address in an rolodex twice. If you look up the address in the first entry, go break all the windows in that house, then go back, look up the address in the second slot in your rolodex, and drive to THAT address, you'll find the house has broken windows (Because both addresses point to the same house.)
Similarly, when you add the same object to an array twice, it's two pointers to the same object. When you change values of the object at index 0, you see those changes reflected in the object in index 1 because it's a second pointer to the same object.
Despite saying the wrong thing about what goes wrong with your code, #Shashi3456643 gave you the correct solution, which is to create a new, unique object for every entry in your array.

Make sure to initiate the array:
NSMutableArray *stack=[[NSMutableArray alloc] init];

This is because every time you init the array. Initialize the array once.
For example:
in .h
Coordinate*c;
in .m
- (void)viewDidLoad
{
c = [[Coordinate alloc] init];
}
-(void)addToStack:(Coordinate *)coord{
c.x=coord.x;
c.y = coord.y;
if (coord.x==0 && coord.y==0) {
c.x=coord.x+1;
[_stack addObject:c];
c.x=coord.x;
c.y=coord.y+1;
[_stack addObject:c];
c.y=coord.y;
}
}

Related

Properties in my model are being duplicated for each item after adding to an array

I am creating a model and then adding that model to an array. However, once I add more than one item, some of the properties in my model ended up being duplicated.I have the following properties of type DrawnLayerModel:
model.overlay
model.fillcolor
model.linecolor
model.overlayString
OverlayString is the property that I'm most concerned with at the moment. Here is where I create the model object and add it to my array:
-(void)saveOverlay {
DrawnLayerModel *model = [self.drawnLayerModel initWithOverlay:self.mapView.overlays.lastObject fillColor:self.customFillColor lineColor:self.customLineColor overlayTitle:self.layerName];
[self.overlaysArray addObject:model];
for (DrawnLayerModel *model in self.overlaysArray) {
NSLog(#"Model ====> %#.", model);
NSLog(#"Title ====> %#.", model.overlayTitle);
}
}
Every time this button is pushed it adds a new model object:
- (IBAction)saveButtonPressed:(id)sender {
UITextField *textfield = alertController.textFields.firstObject;
self.layerName = textfield.text;
[self.helpers createSuccessAlertContoller:self mapView:self.mapView title:#"Layer Successfully Saved!" message:#"Choose the layers button in the navigation bar to access saved layers."];
[self saveOverlay];
}
I get the following output:
2018-02-05 13:47:12.387032-0800 prism[4910:1739598] Model ====> <DrawnLayerModel: 0x1c424d2c0>
2018-02-05 13:47:12.387166-0800 prism[4910:1739598] Title ====> Blue.
2018-02-05 13:47:12.387204-0800 prism[4910:1739598] Model ====> <DrawnLayerModel: 0x1c424d2c0>
2018-02-05 13:47:12.387235-0800 prism[4910:1739598] Title ====> Blue.
Now if you look at the DrawnLayerModel output these numbers are suspiciously the same:
0x1c424d2c0
Is that an address where the object was saved? Why are my properties being duplicated?
Once I add multiple models to my array
The problem is with the code that does that:
DrawnLayerModel *model = [self.drawnLayerModel initWithOverlay:self.mapView.overlays.lastObject fillColor:self.customFillColor lineColor:self.customLineColor overlayTitle:self.layerName];
[self.overlaysArray addObject:model];
You are just reinitializing the same persistent object over and over (self.drawnLayerModel). Thus, you are adding the same object to the array twice (or more). Adding an object to an array doesn't copy it, and an object pointer is merely a reference, so you are able to add multiple references to one object to an array.
The real problem here is that you have broken the most basic law of instantiation in Objective-C: Never say init without having said alloc in the very same set of square brackets. And vice versa: never say alloc without saying init in the same line.

NSArray mutableCopy creates new array but still points to old contents

I have an NSMutableArray called playersArray in my singleton class which holds for my applications main datasource.
Each object of playersArray is a NSDictionary and the content is like :
{
sgfID = 1;
sgfPlayer = "<PlayerContact: 0xbf851b0>";
}
PlayerContact is a NSObject subclass containing properties like:
NSString * playerName, playerTeam, BOOL PlayerSelected and so on.
In one of my ViewControllers, in viewDidLoad, I want to take a deep copy of playersArray in to a NSMutableArray named duplicatePlayersArray. I do this by
playersArray = [[SGFHelper sharedHelpers] SGFContactsArray];
duplicatePlayersArray = [playersArray mutableCopy];
Now that I have two separate copies, I was under the impression that playersArray and duplicatePlayersArray are two totally different arrays in the memory. However I found that they are NOT!
Even if the debugger shows that they have different memory addresses, their contents have same memory addresses. So when i do this:
[((NSMutableDictionary *)[duplicatePlayersArray objectAtIndex:0]) setObject:#"333" forKey:#"sgfID"];
playersArray's dictionary at index:0 has ALSO "333" as key "sgfID" instead of "1" as it used to before the above line of code ran.
BUT, if I run the below code, only then, the two arrays start to differ
[duplicatePlayersArray replaceObjectAtIndex:0 withObject:tempDict];
Still this doesn't address my concern because the two arrays which I wanted to believe are different are still "connected". A change in one, results in the other array to change its contents.
Can you friends please show me a way to DEEP COPY the array I explained the contents of in a way where all of their contents are kept in different objects.
Use initWithArray:copyItems: to copy each entry in the array
NSMutableArray *duplicatePlayersArray = [[NSMutableArray alloc] initWithArray:playersArray copyItems:YES];

Edited UITableViewCell is being stored as a new cell

I have a table view that has a data source in sync with Core Data. However, I'm having a problem. Whenever I edit or delete a tableview cell, and I reload the view, I see a copy of the tableview cell that was there before it was edited. Here's some code to make it clearer.
When the view first loads, it tries to get all the "SOCommands" from "SOModule" which has a one-to-many relationship. Then, it converts it into "SOCommandTemp", so that I can work with them without altering the database.
_serverModuleCommands = [[NSMutableArray alloc]initWithArray:[self.serverModule.socommand allObjects]];
for(int i=0;i<[_serverModuleCommands count];i++)
{
SOCommandTemp* newTemp = [[SOCommandTemp alloc]init];
newTemp.commandName = ((SOCommand*)[_serverModuleCommands objectAtIndex:i]).commandName;
newTemp.sshCommand = ((SOCommand*)[_serverModuleCommands objectAtIndex:i]).sshCommand;
[_serverModuleCommands replaceObjectAtIndex:i withObject:newTemp];
}
Then, when I'm editing cells, I call methods such as these:
[_serverModuleCommands addObject:commandValues]; //commandValues is in the form of SOCommandTemp
[_serverModuleCommands replaceObjectAtIndex:_selectedCommandCell.row withObject:commandValues]; //_selectedCommandCell is an ivar that is cleared immediately after use
Then, when saving, I convert the array into SOCommand by doing this:
for(int j=0; j<[_serverModuleCommands count]; j++){
SOCommand* newCommand = [NSEntityDescription insertNewObjectForEntityForName:#"SOCommand" inManagedObjectContext:self.managedObjectContext];
newCommand.commandName = ((SOCommandTemp*)[_serverModuleCommands objectAtIndex:j]).commandName;
newCommand.sshCommand = ((SOCommandTemp*)[_serverModuleCommands objectAtIndex:j]).sshCommand;
newCommand.somodule = newModule;
}
However, before this is called, I want to make sure that I'm saving only one array item, since I added and editing one cell, so I do this:
NSLog(#"Going to Save: %#",[_serverModuleCommands description]);
And sure enough, I get only 1 array item. Then, I do save it, and exit the view controller. But when the first line:
_serverModuleCommands = [[NSMutableArray alloc]initWithArray:[self.serverModule.socommand allObjects]];
is called again, I'm getting two values in its description, one for the original and one for the edited.
Any help would be great!
~Carpetfizz
In your saving segment, you create a new SOCommand object no matter if it already exist.
Why not just use the actual objects (SOCommand) and edit them, this will not alter your DB information until you save the context.
It will save you some grieve swapping back and forth between your objects.
If you cannot edit in context, you should pass the existing item objectID to your "temp" objects and if it exist, fetch this object from DB and make the update to the existing item:
NSManagedObjectID* oID = ((SOCommandTemp*)[_serverModuleCommands objectAtIndex:j]).objectID;
if(oID) {
SOCommand* cmd = (SOCommand*)[context existingObjectWithID:oID error:nil];
if (cmd) { //no error fetching the object
//update `cmd` with your new values
}
}

NSMutableArray replacing object insted of adding

I'm using a NSMutableArray to store an object called poligonon. This object has a NSMutableArray as property to store coordinates X.
But when I add the second object, the first object on the array transform itself. All objects on the array must be differents, but they are equal the last object in the array.
Exemple:
coordArrayX is a property (NSMutableArray)
-saveDataIntoArray
{
poligonon.coorArrayX = coordArrayX;
arrayPoligonon addObject: poligonon;
}
The first time that the user clicks to save, the first coordinate is 74.
Now, he creates a new poligonon that has coordinate 45, and add to the array.
When the user checks, the first poligonon has coordinate = 45.
How to solve?
Each and every time you are adding the same poligonon to the array and overwriting the value of coorArrayX.
Instead of,
{
poligonon.coorArrayX = coordArrayX;
arrayPoligonon addObject: poligonon;
}
Try this,
{
poligonon = [[Poligonon alloc] init];
poligonon.coorArrayX = coordArrayX;
[arrayPoligonon addObject:poligonon];
}

Object becomes duplicated in NSMutableArray

Im trying to add an object to NSMutableArray it seems to get duplicated.
#interface TestObject : NSObject {
double a_actual;
double a_target;
}
#property(assign) double a_actual;
#property(assign) double a_target;
Create some pointers:
NSMutableArray * myTestObjectArray;
TestObject * myTestObject;
Init them:
myTestObjectArray = [[NSMutableArray alloc] init];
myTestObject = [[TestObject alloc] init];
I add value to the object and add it to the array:
[myTestObject setA_actual:234];
[myJointDataArray insertObject:myTestObject];
I add different values to each object, but i do not necessarily fill all the variables out.
When i print each object out i have the same (last) value duplicated in all objects for some reason.
Printing the array shows that all objects are the same:
Array: (
"<TestObject: 0x6b9b400>",
"<TestObject: 0x6b9b400>",
"<TestObject: 0x6b9b400>",
"<TestObject: 0x6b9b400>",
"<TestObject: 0x6b9b400>",
"<TestObject: 0x6b9b400>" )
Should i alloc a new object of TestObject everytime i want to work with a new?
Should i alloc a new object of TestObject everytime i want to work with a new?
Yes. If you don't allocate a new object, you're just working with the same object over and over again. It appears you want multiple, distinct objects, so allocate a new instance for each one.
To make it more clear to you why it is failing, consider that insertObject: takes a pointer to an object as a parameter. So when you send the insertObject: message to your array, it will store a pointer to that object, not a copy of the object itself. That's why you have to alloc/init a new instance of it.
You are basically adding the same object. If you check the value of "a_actual" for each object inside your array, you will see it's the same. You should allocate a new one and add it.

Resources