Is this a correct declaration of an Array in Objective c? - objective-c

NSArray *arr=[[[NSArray alloc]autorelease]autorelease];

Close, but no cigar.
If you want an autoreleased NSArray, you'd need to use:
NSArray *arr = [[NSArray alloc] init] autorelease];
That said, this will simply get you an empty immutable array, so you'll most likely want to populate it via one of the initWithObjects: style methods. (See the full NSArray class reference for more information.)

Or you can just declare it like this:
[NSArray array];
This gives you an autoreleased instance of the array.

Related

Why mutable object(NSMutableArray and NSMutableDictionary) required alloc- init?while we can directly assign value to immutable objects

//Mutable object...
//first initialize
NSMutablearray *arr=[[NSMutableArray alloc]init];
//then add value
[arr addobjects:#"iPhone",#"Android",nil];
//But we can assign value immutable array without initialize
NSArray *brr=#[#"iPhone",#"Android"];
There are many ways to initialize NSMutableArray. For example:
NSMutableArray *arr = [NSMutableArray arrayWithObjects: #"iPhone", #"Android", nil];
The #[] literal syntax is a fairly new addition to ObjC, and it returns an NSArray (non-mutable), which is why you can't assign it directly to an NSMutableArray. It's just syntactic sugar for [NSArray arrayWithObjects:count:]. If you want to use that syntax, you still can, though:
NSArray *brr = [#[#"iPhone",#"Android"] mutableCopy];
That's just the way the literal syntax is. In Objective-C, it creates an NSArray. If you really want to use the syntax but end up with a mutable array you can use a copy like this:
NSMutableArray *brr=#[#"iPhone",#"Android"].mutableCopy;
This system is much better in Swift, where it's just one value type called Array and you set mutability with either a var or a let
var myArray = ["iPhone", "Android"] // mutable
let myArray = ["iPhone", "Android"] // immutable
You object to the two-step process:
//first initialize
NSMutableArray *arr=[[NSMutableArray alloc]init];
//then add value
[arr addobjects:#"iPhone",#"Android",nil];
And you say you would rather write a literal array:
NSArray *brr=#[#"iPhone",#"Android"];
So combine them:
NSMutableArray* arr = [NSMutableArray arrayWithArray: #[#"iPhone",#"Android"]];
Because the literal's type is immutable. Also, you should remember NSMutableArray is a subclass of NSArray. You can assign an instance of subclass to its superclass, but not otherwise.

Copying a dictionary changes NSMutableArray into NSArray?

So I have this NSMutableDictionary object:
pdata=[[NSMutableDictionary alloc] initWithObjectsAndKeys:
#"",#"pid",
#"",#"pname",
[[NSMutableArray alloc] initWithCapacity:1],#"ilist",
nil];
And then I copy this object into another object like this:
NSMutableDictionary *pdataCopy=[[NSMutableDictionary alloc] initWithDictionary:pdata copyItems:TRUE];
But once Ive done this, pdataCopy.ilist is now an NSArray instead of NSMutableArray.
How can I copy a dictionary object whilst maintaining the mutability of the properies inside it?
Actually you can't. You can get a mutable array by
NSMutableArray *mutableArray = [pdataCopy.ilist mutableCopy]
You have three options:
Don't specify copyItems:YES
Scan through the dictionary after copying and replace NSArrays with NSMutableArrays (using mutableCopy) as desired.
Create your own subclass of NSMutableArray that responds to copyWithZone by producing a mutable copy of itself (and use objects of that class in your dictionary).

How to copy NSArray to another NSArray?

I have many different NSArrays, and according to the users choice I want one of them to be copied to a new NSArray. How do I copy one NSArray to another?
There can be several ways for this-
array1 = [array2 copy];
Use initWithArray method.
You can also use initWithArray:copyItems: method. (This if for NSMutableArray)
you can use the
NSArray *_newArray = [NSArray arrayWithArray:_oldArray];
or if you prefer better, you can use:
NSArray *_newArray = [[NSArray alloc] initWithArray:_oldArray];
(in that case the object of the first array won't be copied, that get only a retain front he second NSArray, you can remove the object from any array it won't affect the other array, but if you change any object in any NSArray it will be changed in the other one as well because there is both of the old and the new array is working with the same instance of the objects.)
if your plan is to make another instance of the old objects in the new array:
NSArray *_newArray = [[NSArray alloc] initWithArray:_oldArray copyItems:true];
if you are using the ARC, you won't need to do anything else, if you are not, in the case of both -initWithArray: or -initWithArray:copyItems: you should use the [_newArray release]; to release the array after you don't want to use anymore.
As well as
NSArray *newArray = [oldArray copy];
if you need to add/remove from the new array, the simplest way to make a mutable copy is:
NSMutableArray *editableArray = [oldArray mutableCopy];
The above functions both make shallow copies, for deep copy it's as #holex and #rishi mentioned
NSArray *newArray = [[NSArray alloc] initWithArray:oldArray copyItems:true];
NSMutableArray *editableArray = [[NSMutableArray alloc] initWithArray:oldArray copyItems:true];

How to append two NSMutableArray's in Iphone sdk or append an NSArray With NSMutableArray?

I need to append two NSMUtableArray's can any one suggest me how it possible?
My code is:
NSMutableArray *array1 = [appDelegate getTextList:1];
NSArray *array2 = [appDelegate getTextList:2];
[array1 addObjectsFromArray:array2];//I am getting exception here.
Anyone's help will be much appreciated.
Thanks all,
Lakshmi.
What's probably happening, is that your [appDelegate getTestList:1] is not actually returning a NSMutableArray, but a NSArray. Just typecasting the array as mutable by holding a pointer to it like that will not work in that case, instead use:
NSMutableArray *array1 = [[appDelegate getTextList:1] mutableCopy];
NSArray *array2 = [appDelegate getTextList:2];
[array1 addObjectsFromArray:array2];
Or you could store the 'textList' variable that you have in your appDelegate as an NSMutableArray in the first place. I am assuming that you have an NSArray of NSArrays (or their mutable versions). Eg.
// In the class interface
NSMutableArray *textLists;
// In the function in which you add lists to the array
NSMutableArray *newTextList;
[self populateArray:newTextList]; // Or something like that
[textLists addObject:newTextList];
Note: that you will probably have a different workflow, but I hope that you get the idea of storing the actual lists as NSMutableArrays.
Another Note: the second method WILL modify in place the NSMutableArray that [appDelegate getTextList:1]; returns
Try this:
NSMutableArray *result =
[[appDelegate getTextList:1] mutableCopy]
addObjectsFromArray:[appDelegate getTextList:2]];
You're getting the exception because you're trying to send mutating messages to an immutable array.

Objective-C accessing / changing array elements in a multidimensional array (NSArray)

I'm trying to change a value in a multidimensional array but getting a compiler error:
warning: passing argument 2 of 'setValue:forKey:' makes pointer from integer without a cast
This is my content array:
NSArray *tableContent = [[NSArray alloc] initWithObjects:
[[NSArray alloc] initWithObjects:#"a",#"b",#"c",nil],
[[NSArray alloc] initWithObjects:#"d",#"e",#"f",nil],
[[NSArray alloc] initWithObjects:#"g",#"h",#"i",nil],
nil];
This is how I'm trying to change the value:
[[tableContent objectAtIndex:0] setValue:#"new value" forKey:1];
Solution:
[[tableContent objectAtIndex:0] setValue:#"new val" forKey:#"1"];
So the array key is a string type - kinda strange but good to know.
NSMutableArray *tableContent = [[NSMutableArray alloc] initWithObjects:
[NSMutableArray arrayWithObjects:#"a",#"b",#"c",nil],
[NSMutableArray arrayWithObjects:#"d",#"e",#"f",nil],
[NSMutableArray arrayWithObjects:#"g",#"h",#"i",nil],
nil];
[[tableContent objectAtIndex:0] replaceObjectAtIndex:1 withObject:#"new object"];
You don't want to alloc+init for the sub-arrays because the retain count of the sub-arrays will be too high (+1 for the alloc, then +1 again as it is inserted into the outer array).
You're creating immutable arrays, and trying to change the values stored in them. Use NSMutableArray instead.
You want either NSMutableArray's insertObject:atIndex: or replaceObjectAtIndex:withObject: (the former will push the existing element back if one already exists, while the latter will replace it but doesn't work for indices that aren't already occupied). The message setValue:forKey: takes a value type for its first argument and an NSString for its second. You're passing an integer rather than an NSString, which is never valid.
Sorry for responding 1 and half years old question :D
I got the same problem, and at last I solved it with counting the elements, then do addObject to push to the array element