how can I save NSMutableArray into NSMutableArray so that previous data in NSMutableArray remain same? - iphone

I want to know that how can I add NSMutableArray in to an NSMutableArray so that previous data should not lost, and new data will be added on next indexes.
If you don't understand it then you can ask again to me,
I will appraise the right answer.
my code is as below
-(void)setArray1:(NSMutableArray *)arrayValueFromNew
{
self.myArray=arrayValueFromNew;
myArray2 = [[NSMutableArray alloc] initWithArray:arrayValueFromNew];
for(int i=0;i<[myArray2 count];i++)
{
[myArray addObject:[myArray2 objectAtIndex:i]];
}
}

In your code, myArray and myArray2, both have same objects as you are assigning the arrayValueFromNew array to both. So it kind of doesn't make sense.
But to answer your question 'how to add one array to another?' do :
[mutableArray1
addObjectsFromArray:array2];
EDIT:
this is how your method should look
-(void)setArray1:(NSMutableArray *)arrayValueFromNew
{
if(!self.myArray)
{
self.myArray = arrayValueFromNew;
}
else
{
[self.myArray addObjectsFromArray:arrayValueFromNew];
}
}
Your 'myArray must be initialized. You can initialize it in viewDidLoad or init:
self.myArray = [[NSMutableArray alloc]
initWithCapacity:1];

NSMutableArray *array1 = [NSMutableArray array], *array2 = [NSMutableArray array];
// add some objects to the arrays
[array1 addObjectsFromArray:array2];
//array1 now contains all the objects originally in array1 and array2

This will work,
NSMutableArray *mutarr=[[NSMutableArray alloc]initWithArray: array1]

It looks like you just want a new copy of the old array. There is a handy function for that
NSMutableArray *newArray = [oldArray mutableCopy];
Remember that you've used copy in getting this array so you are responsible for managing the memory of newArray
EDIT
What is your code doing?
-(void)setArray1:(NSMutableArray *)arrayValueFromNew //1
{
self.myArray=arrayValueFromNew; //2
myArray2 = [[NSMutableArray alloc] initWithArray:arrayValueFromNew]; //3
for(int i=0;i<[myArray2 count];i++)
{
[myArray addObject:[myArray2 objectAtIndex:i]]; //4
}
}
This looks like a setter for a property array1
You are setting the property 'array' to arrayValueFromNew. Since I don't know whether this property has been declared with retain or copy I don't know whether array is a pointer to arrayValueFromNew or a pointer to a copy of arrayValueFromNew
You set myArray2 to be a new array that contains the objects of arrayValueFromNew
For each object in myArray2 (which are the objects from arrayValueFromNew. see point 3) you add this object to myArray. Assuming myArray is an NSMutableArray it started with the objects from arrayValueFromNew which you have now added again. It contains each item in arrayValueFromNew twice.

Related

NSMutableArray of NSMutableArrays. Mutating method sent to immutable object

I have NSMutableArray of NSMutableArrays:
NSMutableArray *array = [[NSMutableArray alloc]init];
for (int i = 0; i < 5; i++)
{
NSMutableArray *miniArray = [[NSMutableArray alloc]init];
for (int k = 0; k < 30; k++)
{
[miniArray addObject:#"0"];
}
[array addObject:miniArray];
}
Then, when I try to do this:
[[array objectAtIndex:packIndex]replaceObjectAtIndex:index withObject:#"1"];
it crashes with: [__NSCFArray replaceObjectAtIndex:withObject:]: mutating method sent to immutable object'
Why ? How to fix ? Thanks !
UPD:
I save this array in NSUserDefaults:
[defaults setObject:array forKey:#"mainArray"];
Then, I read it in the other class:
array = [[NSMutableArray alloc]initWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"mainArray"]];
Also, I must to mention that sometimes the code runs well and it changes "0" to "1". But it also crashes sometimes. So I cant see the logic, why it works fine or why it crashes sometimes.
The problem is that when you read the array out of NSUserDefaults, the mini-arrays are not automatically NSMutableArrays.
Try this:
array = [[NSMutableArray alloc]initWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"mainArray"]];
for(int i = 0; i < array.count; i++) {
NSArray * tempArray = array[i];
array[i] = [tempArray mutableCopy];
}
Edit:
Best Coder's answer explains why this is.
Objects stored in NSUserDefaults are stored as immutable versions, basically NSUserDefaults is a plist and there is no flag marking an array as mutable/immutable so when you read them back out, they are assumed to be immutable.
Values returned from NSUserDefaults are immutable, even if you set a
mutable object as the value. For example, if you set a mutable string
as the value for "MyStringDefault", the string you later retrieve
using stringForKey: will be immutable.
Instead, make a mutableCopy of the array you retrieve from NSUserDefaults, add your object, then set your new array back in.
see this link:
https://developer.apple.com/documentation/foundation/nsuserdefaults
Try using more verbose code:
NSMutableArray *tempArray = [array objectAtIndex:packIndex];
[tempArray replaceObjectAtIndex:index withObject:#"1"];

Empty NSMutableArray , not sure why

Ok so I populate the array like this:
NSMutableArray *participants;
for(int i = 0; i < sizeofpm; i++){
NSDictionary *pmpart_dict = [pm_participants objectAtIndex:i];
NSString *pmpart_email = [pmpart_dict objectForKey:#"email"];
NSString *pmpart_email_extra = [#"pm" stringByAppendingString:pmpart_email];
[participants setValue:pmpart_email forKey:pmpart_email_extra];
NSLog(#"%#", participants);
}
sizeofpm is 1. that is using count. to get the number of values in the array. How can i store values to that array? It doesnt seem to be working. Thanks!
you need to alloc it first. Try to change the first line to:
NSMutableArray* participants = [[NSMutableArray alloc] init];
also using setValue:forKey: wont work with an NSMutableArray as an array has no key.
Try using [participants addObject:pmpart_email];.
You don't create the array, you just declare it.
NSMutableArray *participants = [NSMutableArray array];
After that, setValue:forKey: will not add objects to an array. You need addObject::
[participants addObject:pmpart_email];
There is no key.
You are assigning a value to an NSMutableArray *participants like how you assign values to an NSDictionary object. To assign values to NSMutableArray you can call - (void)addObject:(id)anObject
So, I as some of the other answer have stated, you're missing your initializer for participants. However, judging by your use of setValue:forKey:, and how you appear to be structuring your data, you're not looking for NSMutableArray, but instead NSMutableDictionary. Arrays are simply lists, whereas dictionaries maintain key-value relationships, which you appear to be attempting to leverage.
Try this:
// some classes provide shorthand for `alloc/init`, such as `dictionary`
NSMutableDictionary *participants = [NSMutableDictionary dictionary];
for(int i = 0; i < sizeofpm; i++){
NSDictionary *pmpart_dict = [pm_participants objectAtIndex:i];
NSString *pmpart_email = [pmpart_dict objectForKey:#"email"];
NSString *pmpart_email_extra = [#"pm" stringByAppendingString:pmpart_email];
[participants setValue:pmpart_email forKey:pmpart_email_extra];
NSLog(#"%#", participants);
}
This will give you a dictionary in the form of
{
pmpart_email_extra: pmpart_email
}

Instantiate an NSArray passing a mutable array changes array to mutable?

If I instantiate an NSArray passing it an NSMutableArray, does it become a NSArray or does it just appear to be one.
i.e. is the mutable array eventually released
- (NSArray *)getObjectivesWithPerspective:(Perspective *)perspective
{
NSMutableArray *result = [NSMutableArray array];
for (ObjectiveManagedObject *objective in self.objectives)
{
if (objective.perspective.objectID == perspective.objectID) {
[result addObject:objective];
}
}
return [NSArray arrayWithArray:result];
}
See this answer: https://stackoverflow.com/a/1392051/254422
Basically, it copies the objects into a new, autoreleased, immutable NSArray.
The NSMutableArray created using +array is autoreleased.
You can find some info about this here: what does -arrayWithArray actually DO?. But the array you get back should be immutable. NSArray will copy the references into an immutable array.
If in doubt do a test. Get an array back from the method, cast it as a NSMutableArray and try to add an object. You should get an error when you do this.
As NSMutableArray is a subclass of NSArray, you can return result directly without the need to create a new NSArray object:
- (NSArray *)getObjectivesWithPerspective:(Perspective *)perspective
{
NSMutableArray *result = [NSMutableArray array];
for (ObjectiveManagedObject *objective in self.objectives)
{
if (objective.perspective.objectID == perspective.objectID) {
[result addObject:objective];
}
}
return result;
}

Synthetise an NSMutableArray

for(int i=0;i<[promotionArr count];i++)
{
// NSLog(#"ok");
Promotion *prom = [[Promotion alloc]init];
prom.pName=[[promotionArr objectAtIndex:i] objectForKey:#"name"];
prom.pUrl=[[promotionArr objectAtIndex:i] objectForKey:#"url"];
prom.pDescription=[[promotionArr objectAtIndex:i] objectForKey:#"description"];
[promMUAraay addObject:prom];
NSLog(#"number of elements : %d",[promMUAraay count]);
}
But the number of element is always 0 . I haven't do #synthetise for the NSMutableArray , xcode tell me that i can't .I just do this in my .h
NSMutableArray *promMUAraay;
It's that the problem ?
Have you remembered to alloc, init the array?
NSMutableArray *array = [[NSMutableArray alloc] init];
Do this before you use the array.
You should initialize your NSArray before accessing it. That is, in your .m file, in your -init method, you should have some code like this:
promMUAraay = [[NSMutableArray alloc] init.......];
For all the options you have initializing an NSArray, see the NSArray reference.
As to your attempt at syntethizing the array, the #synthetize keyword is used to automatically create definitions for setter/getter methods to your array (provided you have a corresponding #property declaration in your interface). This does not change things in that you would all the same need to initialize your NSArray in the init method of your class. The only thing is that you could thereafter refer your variable using the dot-notation: self.promMUAraay.

How to copy one NSMutableArray to another?

I have an nsmutablearray(xmlParseArray) having values firstname and id, I want to copy only firstname into another nsmutablearray(copyArray).
How can I do this?
Assumption: your xmlParseArray contains number of objects all of which have a firstname property and and an id property
NSMutableArray* nameArray = [[xmlParseArray valueForKey: #"firstname"] mutableCopy];
// nameArray is an array you own.
-valueForKey: when sent to an array causes the message -valueForKey: to be sent to each of its elements and a new array to be constructed from the return values. The -mutableCopy ensures that the result is then turned into a mutable array as per your question.
I'm guessing you mean that the first array, xmlParseArray, contains a list of NSDictionary objects which each have objects attached to the keys "firstname" and "id". One way to accomplish that would be like this:
NSMutableArray *copyArray = [[NSMutableArray alloc] initWithCapacity:[xmlParseArray count]];
for(NSDictionary *dict in xmlParseArray)
if([dict objectForKey:#"firstname"])
[copyArray addObject:[dict objectForKey:#"firstname"]];
// ...do whatever with copyArray...
[copyArray release];
NSMutableArray *arr = [NSMutableArray arrayWithObject:[copyArray objectAtIndex:0]];
or
[arr addObject:[copyArray objectAtIndex:0]];
[arr addObject:[copyArray objectAtIndex:1]];
NSMutableArray *newArray = [oldArray mutableCopy];
or
NSMutableArray *newArray = [NSMutableArray arrayWithArray:oldArray];
be aware that the objects in the array aren't copied, just the array itself (references to objects are maintained).