I have a mutable array of values used in a tableviewcontroller, a mapviewcontroller, and the callingviewcontroller. I have been updating them all, ie.
[dataArray addObject:object atIndex:0];
[tvc. dataArray addObject:object atIndex:0];
[mvc. dataArray addObject:object atIndex:0];
Is there a way of declaring dataArray in the table and map viewcontrollers that would make them pointers to the dataArray in the callingViewController? So I would just have to update one?
***Okay guys, I made a really stupid mistake here. At some point I changed the initialization and passed nil as the dataArray, and for some reason I had an "if (!dataArray) create new" clause to hide it from myself.
Kaan is correct.
[dataArray addObject:object atIndex:0];
is all that is needed.
This is a little more involved but I think would be the best solution. You should have some way for all of these different ViewControllers to reference a single object that is managing your data. This could be a delegate, or it could be a singleton that owns the main dataArray.
Search here or on google for both of those terms and you should be able to get started with either route.
After your comment:
How about you declare a property called dataArray in both your tableView and mapView and also callingView. Then, in your callingViewController, you initialize a mutable array called lets say myFirstArray and do:
NSMutableArray *myFirstArray = [NSMutableArray array];
self.dataArray = myFirstArray;
myTableView.dataArray = myFirstArray;
myMapView.dataArray = myFirstArray;
This way they will both be pointing to the same object and change you do in one will reflect in the other. Give it a try!
if you create the array in the AppDelegate class then you can access from any other classes within your app.
Related
I am parsing JSON and storing that data into NSMutableArray on my homepage. I want to access that data on my other page not after the another, so I am using Singleton Pattern for sharing common data in my homepage. I am storing that NSMutableArray data to Singleton file for common access. In second page i am showing that data in tableview. There is one button which modifies the data but will not change original data i.e homepage arraydata. So I am storing that data into clonearray and updating that clonearray. But when I return back to homepage and in ViewDidAppear after placing breakpoint I am observing my original data is changed.
Please have a look on this issue and correct me where I am doing wrong with my code.
For more reference I added the project link please download and check this: [Project Link][1]
In this project I have created the 2 View Controllers , 1 model class, and one Singleton for common data across all file.
View Controller:
In this file I am parsing JSON and storing in NSMutableArray and also setting the same array data to Singleton file array for common access across all file.
SecondViewController:
In this file I am getting array data from Singleton file and storing in local array.
There is one button to modify data. In modify data function I am modifying the data and storing in the other array for common access (clonearray).
But when I return back to First View Controller and in ViewDidAppear after placing breakpoint, I am observing my original data is changed.
Please check, I don't want my original data to be changed. Please check and suggest me where I am doing wrong with my code.
Your problem because all your property( ViewController->shippingArray, SecondPageController->myshippingarray, PersonDtklSingleton->shippingAddress) point to same array.
You can fix problem by clone array with Deep Copies, to copy original to new array. Make sure all items in original array adopted NSCopying.
SecondPageController
#implementation SecondPageController
...
- (void)viewDidLoad {
[super viewDidLoad];
myshippingarray=[[NSMutableArray alloc]init];
// deep copy
self.myshippingarray = [[NSMutableArray alloc] initWithArray:[[PersonDtklSingleton sharedInstance]shippingAddress] copyItems:YES];
// Do any additional setup after loading the view.
}
...
#end
PersonModel
#implementation PersonModel
#synthesize housernumber,resident,street,city,pincode,defaultAddress;
- (id)copyWithZone:(NSZone *)zone {
PersonModel *copyObj = [PersonModel new];
copyObj.housernumber = [self.housernumber copyWithZone:zone];
copyObj.resident = [self.resident copyWithZone:zone];
copyObj.street = [self.street copyWithZone:zone];
copyObj.city = [self.city copyWithZone:zone];
copyObj.pincode = [self.pincode copyWithZone:zone];
copyObj.defaultAddress = [self.defaultAddress copyWithZone:zone];
return copyObj;
}
#end
If I did't wrong when you update the data it change both of your data since it's referencing the same memory
you need to alloc a new memory and copy the data into a new array
like this
NSMutableArray *newArray=[[NSMutableArray alloc] initWithArray:originalArray copyItems:YES];
You just update the newArray and the original one won't be affected
I am trying to check if the NSMutableArray has a specific object, before adding the object to it, if exists then don't add.
i looked over many posts explaining how to do this, managed to implement it like this, but it always gives me that the object "doesn't exist", though i already added it !
//get row details into FieldLables Object
AllItemsFieldNames *FieldLabels = feedItems[row];
// object to hold single row detailes
AllItemsFieldNames *SelectedRowDetails = [[AllItemsFieldNames alloc] init];
SelectedRowDetails.item_name = FieldLabels.item_name;
//SelectedRowDetails.item_img = FieldLabels.item_img;
SelectedRowDetails.item_price = FieldLabels.item_price;
//NSLog(#"item has been added %#", SelectedRowDetails.item_name);
//NSLog(#"shopcartLength %lu", (unsigned long)SelectedFieldsNames.count);
if([SelectedFieldsNames containsObject:SelectedRowDetails])
{
NSLog(#"Already Exists!");
}
else
{
NSLog(#"Doesn't Exist!");
[SelectedFieldsNames addObject:SelectedRowDetails];
}
I can display all object from the NSMutableArray into a table, what i need to do in the above code is stop the addition of duplicate objects.
The first method listed on the NSArray documentation under the section "querying an array" is containsObject:. If it's not working, that suggests that your implementation of isEqual: is not correct. Make sure you follow the note in the documentation:
If two objects are equal, they must have the same hash value. This
last point is particularly important if you define isEqual: in a
subclass and intend to put instances of that subclass into a
collection. Make sure you also define hash in your subclass.
You might also consider using an NSSet since you can't add duplicates to that. Of course, this would also require a working version of isEqual:.
Sets are composed of unique elements, so this serves as a convenient way to remove all duplicates in an array.
here some sample,
NSMutableArray*array=[[NSMutableArray alloc]initWithObjects:#"1",#"2",#"3",#"4", nil];
[array addObject:#"4"];
NSMutableSet*chk=[[NSMutableSet alloc ]initWithArray:array]; //finally initialize NSMutableArray to NSMutableSet
array= [[NSMutableArray alloc] initWithArray:[[chk allObjects] sortedArrayUsingSelector:#selector(compare:)]]; //after assign NSMutableSet to your NSMutableArray and sort your array,because sets are unordered.
NSLog(#"%#",array);//1,2,3,4
It is a simple pull to refresh case. I have data loaded into table and have a mutable data array at back-end, I receive a array of new data and want to add this complete array at start of existing array.
One workaround is to create new array with new arrived data and then add previous array into it using addObjectsFromArray: method. Is there some workaround to add new data array to the start of previous array directly?
First, build an NSIndexSet.
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:
NSMakeRange(0,[newArray count])];
Now, make use of NSMutableArray's insertObjects:atIndexes:.
[oldArray insertObjects:newArray atIndexes:indexes];
Alternatively, there's this approach:
oldArray = [[newArray arrayByAddingObjectsFromArray:oldArray] mutableCopy];
NSMutableArray offers the insertObjects:atIndexes: method, but it's easier to append the way you suggest using addObjectsFromArray:.
-insertObject:atIndexes: is easy enough, and should (I believe) be more efficient than using -addObjects and swapping arrays. It'd probably end up looking something like this:
[existingResults addObjects:newResults atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, newResults.count)]]`
Creating a new array is probably your best solution, but you can also use a loop
NSUInteger index;
index = 0;
for ( id item in sourceArray )
{
[destArray insertObject:item atIndex:index];
index++;
}
Just simple way:
NSMutableArray *arrayTmp = [firstArr addObjectsFromArray:myArray];
myArray = arrayTmp;
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];
}
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.