In my code, I must to store an array inside another array:
What's the best way?
first:
NSArray *arrayTemp = myArray;
second:
NSMutableArray *arrayTemp = [[NSMutableArray alloc]init];
[arrayTemp addObjectsFromArray:myArray];
...instruction....
[arrayTemp release];
By doing arrayTemp = myArray, you declare arrayTemp as a new pointer to your existing array myArray. That's not a copy (if you put X in myArray[42], arrayTemp[42] will also be X).
The second variant looks like you're doing a copy of your array, but still the array's values are copied by reference (by pointer), when you seem to need a copy "by value".
What you should try is simply:
NSArray *arrayCopy = [myArray copy];
Beware: from a memory management point of view, this is equivalent to a retain or a alloc/init: you should release your arrayCopy after use.
Related
I am trying to add two arrays into the third array i.e one array's objects are values to the third array and other array's objects are keys to the third array and I am getting the output as null , Is this a right way to do.
NSArray *newcontactkeys,*newcontactvalues ;
NSMutableArray *autoSyncDataArray;
newcontactkeys=[self.resultDict objectForKey:#"keys"];
newcontactvalues=[self.resultDict objectForKey:#"values"];
[autoSyncDataArray setValue:[self.resultDict objectForKey:#"values"]
forKey:[self.resultDict objectForKey:#"Keys"]];
NSLog(#"autosyncArray is %#",autoSyncDataArray);
Output: autosyncArray is (null)
You are using an array, which is an indexed collection, but talking about keys, dictionaries are keyed collections.
NSDictionary has a class method to directly create a dictionary from two arrays, use this and your code becomes, updating to modern Obj-C syntax:
NSArray *newContactKeys = self.resultDict[#"keys"];
NSArray *newContactValues = self.resultDict[#"values"];
NSDictionary *autoSyncDataDict = [NSDictionary dictionaryWithObjects:newContactValues
forKeys:newContactsKeys];
HTH
You're not initialising your array.
NSMutableArray *autoSynchDataArray = [NSMutableArray new]
Also use addObject instead of set value:
[autoSyncDataArray addObject:[self.resultDict objectForKey:#"values"]
You cannot join/Manipulate multiple Array of type NSArray.
Create a NSMutableArray which allows reordering and manipulation of data in it. You can add any number of objects to it, rearrange it and delete it.
NSMutableArray *templateArray = [NSMutableArray new];
There are 2 issues:
Null issue: You are not initializing array. So you will have to use below statement:
NSMutableArray *autoSyncDataArray = [[NSMutableArray alloc] init];
Key/Value Pair: If you want to put keys and values in an array. It will not work like Dictionary. It will go into sequential form. If you are ok with sequential form then use:
[autoSyncDataArray addObject:[self.resultDict objectForKey:#"keys"]];
[autoSyncDataArray addObject:[self.resultDict objectForKey:#"values"]];
otherwise use:
NSMutableDictionary *autoSyncDataDict = [[NSMutableDictionary alloc] init];
[autoSyncDataArray setValue:[self.resultDict objectForKey:#"values"]
forKey:[self.resultDict objectForKey:#"Keys"]];
What is the difference between
NSArray *arr1 = [[NSMutableArray alloc] init];
NSDictionary *dict1 = [[NSMutableDictionary alloc] init];
and
NSMutableArray *arr2 = [[NSMutableArray alloc] init];
NSMutableDictionary *dict2 = [[NSMutableDictionary alloc] init];
I know both (arr1, dict1, arr2, dict2) are going to create NSMutableArray and NSMutableDictionary object respectively, arr1 and dict1 would have access to all the functions that could be accessed by arr2 and dict2.
My Question to you guys is:
What is the difference between arr1 and arr2 or dict1 or dict2? Why would any one make object like arr1 and dict1 when we could do same things by making objects like arr2 and dict2? Are there any benefits of initializing objects like arr1 and dict1 over arr2 and dict2? If none, what could be the use of initializing objects like this?
arr1 is a reference to NSArray which gets an instance of a specialization of NSArray assigned, that is NSMutableArray. (NSMutableArray class inherits from NSArray and adds some methods to modify the array)
The compiler will prevent you from modifying arr1. (However, in Obj-C you could still call the NSMutableArray methods on arr1 during runtime when the object actually is of type NSMutableArray, but that is a different topic and not a proper way of doing it. See below for a better way of modifying arr1 if it really is mutable.)
The same applies for dic1.
arr2 and dict2 on the contrary are references to NSMutableSomething. Therefore those methods that belong to the mutable classes but not to their immutable base class can be accessed in code.
Some addition: Later in your code you could assign (and cast) arr1 to arr2 and then access the methods of NSMutableArray. Before assigning and casting a reference to a base class to a reference to a specialzation, you should always check the current class by isKindOfClass: method of NSObject.
Sampe:
if ([arr1 isKindOfClass:[NSMutableArray class]]) {
arr2 = (NSMutableArray*) arr1;
// Do something with arr2 that requires its mutability.
}
Mutable types have some special privileges like runtime update/insert/delete object from collection.
But they must have to be initialise before use and they occupies more memory than immutable.
Where else immutable type collection can not be alter at runtime. They are static containers as and contains elements which can't be alter from collection.
Immutable does not need to be alloc init and they consume less memory than mutable.
In short NSArray is not flexible. You can't add or remove object into it. Same goes for NSDictionary. You can initialize but dynamic cast will occur and you will have in arr1 simply NSArray.
Difference is simple
1-Mutable classes are those which could be changed after initialization but other can't be changed using SetObject: or SetValue: etc.
2-Mutable classes dynamically create on heap other are created on stack.
I prefer immutable on mutable because if mutable is exposed then other can
change its data using setobject or setvalue and may be we don't know about it.
but if immutable is exposed then we can't change its data so data remain protected.
I want to make array of float type.
Anybody can help me?
NSArray *arrOfFloat = [[[NSArray alloc]initWithObjects:[12.2, 23.44], nil]];
But i want to make array dynamically.
But i want to make array dynamically.
This means you'll have to use an NSMutableArray.
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:#1.1];
[array addObject:#2.2];
...
You also can't add primitives to an array. You'll need to add objects. Notice the # I added before the numbers. This creates number literals.
If you have the floats you want to add as variables, you can auto boxing like this:
[array addObject:#(myFloatVariable)];
Use NSMutableArray class instead of a NSArray (this is a subclass of it), this way, within your code, you will be able to call :
NSMutableArray *yourArray = [NSMutableArray new];
[yourArray addObject:#(1.0f)];
NSArraycan only store objects, so in your case you would have to store your float as NSNumber. If you want to store objects dynamically, thus adding or removing them to an NSArray you have to use the mutable object type called NSMutableArray.
You'll need to wrap your float's in an NSNumber:
[NSNumber numberWithFloat:12.2];
If you're dynamically adding elements to an array, you need to use NSMutableArray.
NSMutableArray *array = [NSMutableArray array];
[array addObject:[NSNumber numberWithFloat:12.2]];
You can use NSMutableArray for example named arrOfFloat and add this :
[arrOfFloat addObject:[NSNumber numberWithFloat:3.5]];
[arrOfFloat addObject:[NSNumber numberWithFloat:23.44]];
Hope, It will may helpful to you.
arrayOfElements = [NSMutableArray arrayWithArray:[someObj getArray]];
and
arrayOfElements = [[NSMutableArray alloc] init];
arrayOfElements = [someObj getArray];
What's the difference?
The first arrayOfElements does not seem to lose its objects when it returns count in numberOfRowsInSection:(NSInteger)section, but the second one does. I get EXC_BAD_ACCESS when I do it the second way.
EDIT:
Can I suppose now that this is the best way,
arrayOfElements = [[NSMutableArray alloc] initWithArray:[someObj getArray]];
because I am initializing an array with the contents of whatever will be autorelease'd, and I now have a fully independent array in the current class, that is viewDidLoad, oops sorry, ViewController.
This line creates an NSMutableArray from an existing array
arrayOfElements = [NSMutableArray arrayWithArray:[someObj getArray]];
This combination first creates an NSMutableArray and then instantly discards it replacing it with what is returned by [someObj getArray]
arrayOfElements = [[NSMutableArray alloc] init]; // Create new NSMutableArray
arrayOfElements = [someObj getArray]; // Throw away the newly created array and replace with the result of [someObj getArray]
If you are not using ARC then it is purely by luck that either would work.
In both cases arrayOfElements is being assigned an autorelease'd object - which will be cleared soon (most likely the next runloop). It is only by chance that nothing else has been written over this point of memory which allows one of your implementations to still work.
If you are not using ARC then really you should update your project to be using it will handle a lot of cases like this for you.
You should definitely be using properties (not bare ivars) as this will help reduce memory issues (for non-ARC) and give a more consistent interface to your code.
In your header (or class extension) declare the property like this
#property (nonatomic, strong) NSMutableArray *arrayOfElements;
Now for ARC you can simple do
[self setArrayOfElements:[[someObj getArray] mutableCopy];
for non-ARC you can do
NSMutableArray *array = [[someObj getArray] mutableCopy];
[self setArrayOfElements:array];
[array release]; array = nil;
Also note that getArray is a bad method name.
The use of “get” is unnecessary, unless one or more values are returned indirectly.
Coding Guidelines
When you are adding objects to mutable array from another array, try this:
[arrayOfElements addObjectsFromArray: [someObj getArray]];
If you're not using ARC, you need to make sure its retained.
if (arrayOfElements) {
[arrayOfElements release];
}
arrayOfElements = [[NSMutableArray alloc] initWithArray:[someObj getArray]];
I have an NSMutableArray (detailsMA)having 100 strings like #"True".
Am storing that array in NSMutableDictionary which is already allocated.
NSArray *array1 = [[NSArray alloc] initWithArray:detailsMA];
[detailsDictionary setObject: array1 forKey:#"detailsMA"];
Now i changed the values of detailsMA, like replacing strings to #"False", After that am retrieving the original array values,
[detailsMA removeAllObjects];
[detailsMA addObjectsFromArray:[detailsDictionary objectForKey:#"detailsMA"]];
Here am getting modified values, not the original values.
I need original values.
Please help me.
You should copy the array.
NSArray *array1 = [[NSArray alloc] initWithArray:detailsMA copyItems:YES];
Don't forget to implement the NSCopying protocol in the classes for the objects to be copied
EDIT:
When you add the objects again, make a copy before adding.
[detailsMA addObjectsFromArray:[[NSArray alloc] initWithArray:[detailsDictionary objectForKey:#"detailsMA"] copyItems:YES]];