Can't properly retrieve objects from NSMutableArray - ios

I will be putting a variety of things in this mutable array, but first I am just trying to make sure it works by putting in strings, and then pulling out the strings. Here is my code
str1=#"1";
str2=#"2";
str3=#"3";
NSMutableArray *testArray;
[testArray addObject:str1];
[testArray addObject:str2];
[testArray addObject:str3];
retrieve =[testArray objectAtIndex:1];
NSLog(#"the test number is %#",retrieve);
The problem is that my string:retrieve equals "null" after receiving the string from the array. I'm not sure what I am doing wrong, I've looked at Apple's documentation but I'm having trouble making sense of it. I know I must be interacting with the array incorrectly, but I'm not sure how exactly. Help will be appreciated.
-Thank you!

You did not initialize your testArray:
NSMutableArray *testArray = [NSMutableArray array];
You can populate the array using new syntax. If you needed mutability only to add the three items, you could use a non-mutable array instead, like this:
NSArray *testArray = #[ #"1", #"2", #"3"];
If you do need mutability, call mutableCopy:
NSMutableArray *testArray = [#[ #"1", #"2", #"3"] mutableCopy];

Well, that's because testArray is nil. you should change the 4th line to
NSMutableArray *testArray = [NSMutableArray array];

You array is nil.
You are missing
NSMutableArray *testArray = [NSMutableArray array];

To clarify what others are telling you:
This line
NSMutableArray *testArray;
Does not create an array. It creates a pointer variable that can be used to point to a mutable array. It starts out containing a zero value (nil, points to nothing.)
It's like a postal address that points to an empty lot.
You need to create (allocate) and initialize a mutable array object in order to use it. (Continuing our analogy, you have to build a house and put a mailbox in front of it before the address becomes valid.)
So you need to say:
testArray = [#[ #"1", #"2", #"3"] mutableCopy];
Breaking that down:
The inner part,
#[ #"1", #"2", #"3"]
Creates an immutable array that contains 3 string objects.
Then we ask the immutable array to create a mutable copy of itself. We save the address of that newly created mutable array into the pointer variable testArray.
We could do it in 3 steps:
NSMutableArray *testArray;
NSArray *tempArray = #[ #"1", #"2", #"3"];
testArray = [tempArray mutableCopy];
Or all at once, like #dasblinkenlight's code:
NSMutableArray *testArray = [#[ #"1", #"2", #"3"] mutableCopy];

Related

Join objects in sub-array into one array - Objective-c

Is there a one-liner to do the following
NSMutableArray *allpoints = [[NSMutableArray alloc] init];
for (NSMutableArray *arr in self.points)
[allpoints addObjectsFromArray:arr];
I have an array of arrays (self.points) and I am joining all of the objects in the subarrays into a single array.
NSArray *array1 = #[ #"a", #"b", #"c" ];
NSArray *array2 = #[ #"d", #"e", #"f" ];
NSArray *array3 = #[ array1, array2 ];
NSArray * flattenedArray = [array3 valueForKeyPath:#"#unionOfArrays.self"];
NSLog(#"flattenedArray: %#", flattenedArray);
Output:
flattenedArray: (
a,
b,
c,
d,
e,
f
)
There is not a way to add all objects in an array of arrays (e.g., every NSMutableArray in self.points to another array without iterating through.
However, you could add a category to NSArray to do exactly what you're doing now, and then call it with one line later.
If you are initializing the array and adding objects at the same time then there is an initializer for that.
NSMutableArray *allpoints = [[NSMutableArray alloc] initWithArray:self.points];
If you already have the mutable array defined and you want to just append objects to the end then you can use the following.
[allpoints addObjectsFromArray:self.points];
I don't think there is a way to do this.
NSMutableArray *allpoints = [[NSMutableArray alloc] initWithArray:self.points]
would give you an array of the arrays, but there is no single line solution. I'd suggest writing a category that will do this for you so you can easily reuse it.

NSMutableArray in NSMutableArray as a single object

I am trying to add NSMutableArray in another NSMutableArray. But what I am trying to do is nested arrays.
My current code is:
NSMutableArray *array1 = [NSMutableArray arrayWithObjects: #"Red", #"Green", #"Blue", #"Yellow", nil];
NSMutableArray *array2 =[[NSMutableArray alloc] init];
[array2 addObject:array1];
This code is adding 4 objects in array2 but I want it to add array1 as single object.
Edit: This code is working I know but in my case in XCode something is wrong with initializing and it is adding 4 objects. I still could not figure it out. So this piece of code is working properly. So the problem was about initialization in a for loop.
I copy/pasted your code, and it adds one object to array2, not four.
Printing description of array2:
<__NSArrayM 0xc46c7b0>( <-- THIS ARRAY HAS 1 OBJECT
<__NSArrayM 0xc488770>( <-- THIS ARRAY HAS 4 OBJECTS
Red,
Green,
Blue,
Yellow
)
)
You may be are getting confused by the fact that printing the description, prints the contents of the inner array also.
Try:
NSMutableArray *array2 =[[NSMutableArray alloc] initWithArray:array1];
i am using this and its working
NSArray *array1 = #[array2, array3, ...];

Creating NSArray from NSMutable Array

At the moment I'm creating an array as per below:
NSArray *data = #[#[#20, #40, #20, #60, #40, #140, #80],];
However I'd like to be able to create the same array from data already in an NSMutableArray.
I've tried this but the library I'm passing the array to does not like it.
NSArray *data = [NSArray arrayWithArray:self.altData];
("altData" is an NSMutableArray)
Any ideas?
An NSMutbaleArray is a subclass of an NSArray. So you can just do NSArray *immutable = [myMutableArray copy] or if you know that you're not going to change the mutable array after a point then you can do NSArray *immutable = mutableArray; maybe followed by mutableArray = nil. Your solution is also fine.

Add other object to NSArray

I made a small code
NSArray* _options = [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:[UIImage imageNamed:#"2"],#"img",name,#"text"
, nil],nil];
Now, I want add other object to _options. What should i do?
I make more test but no success.
Thank for all
you can use [NSArray arrayByAddingObject:]
_options = [_options arrayByAddingObject:object];
or change _options to NSMutableArray
NSMutableArray *_options = [NSMutableArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:[UIImage imageNamed:#"2"],#"img",name,#"text"
, nil],nil];
[_options addObject:object];
and you may want to use modern syntax
NSMutableArray *_options = [#[#{#"img":[UIImage imageNamed:#"2"],#"text":name}] mutableCopy];
[_options addObject:object];
NSArray does not allow any changes to be made; you can use an NSMutableArray instead like this:
NSMutableArray *mutable = [_options mutableCopy];
[mutable addObject:yourObject];
NSDictionary is same in that it can't be mutated.
You can't add objects to a NSArray, to do so, you need a NSMutableArray.
However, you can add objects to NSArray when creating it with : arrayWithObjects
First, create an NSMutableArray, as you can make changes to it as you see fit later throughout your code:
NSMutableArray *newOptions = [NSMutableArray alloc]init];
[newOptions setArray:_options];
[newOptions addObject:yourObject];

NSArray sortedArrayUsingDescriptors: New Copy or Retain?

According to NSArray class reference there are 4 type of methods to sort array:
1- sortedArrayUsingComparator:
2- sortedArrayUsingSelector:
3- sortedArrayUsingFunction:context:
4- sortedArrayUsingDescriptors:
For first three methods it mentioned :
The new array contains references to the receiving array’s elements, not copies of them.
But for the forth method (descriptor) it mentioned:
A copy of the receiving array sorted as specified by sortDescriptors.
But following example shows like the other 3 methods, descriptor also retain original array and do not return a new copy of it:
NSString *last = #"lastName";
NSString *first = #"firstName";
NSMutableArray *array = [NSMutableArray array];
NSDictionary *dict;
NSMutableString *FN1= [NSMutableString stringWithFormat:#"Joe"];
NSMutableString *LN1= [NSMutableString stringWithFormat:#"Smith"];
NSMutableString *FN2= [NSMutableString stringWithFormat:#"Robert"];
NSMutableString *LN2= [NSMutableString stringWithFormat:#"Jones"];
dict = [NSDictionary dictionaryWithObjectsAndKeys: FN1, first, LN1, last, nil];
[array addObject:dict];
dict = [NSDictionary dictionaryWithObjectsAndKeys: FN2, first, LN2, last, nil];
[array addObject:dict];
// array[0].first = "Joe" , array[0].last = "Smith"
// array[1].first = "Robert" , array[1].last = "Jones"
NSSortDescriptor *lastDescriptor =[[NSSortDescriptor alloc] initWithKey:last
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)];
NSSortDescriptor *firstDescriptor =[[NSSortDescriptor alloc] initWithKey:first
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)];
NSArray *descriptors = [NSArray arrayWithObjects:lastDescriptor, firstDescriptor, nil];
NSArray *sortedArray = [array sortedArrayUsingDescriptors:descriptors];
// array[1] == sortedArray[0] == ("Robert" , "Jones")
// comparing array entries whether they are same or not:
NSLog(#" %p , %p " , [array objectAtIndex:1] , [sortedArray objectAtIndex:0] );
// 0x10010c520 , 0x10010c520
it shows objects in both arrays are same,
"A copy of the receiving array sorted as specified by sortDescriptors" means that the array object is copied not the elements in the array. The reason the documentation uses the word "copy" is to make it clear that the returned array is not the same array instance as the receiver.
Elements in an array are never copied in Cocoa with the exception of initWithArray:copyItems:YES which will copy the first level items in the original array to the new array. Even then, this copy is done by calling copyWithZone: on the elements, so caveats apply depending on what elements are in your array.
Note that Cocoa is reference counted, so the concept of "deep copies" is not inherently built in for a reason. This is also (in part) the reason why array objects in cocoa come in two flavors (NSArray and NSMutableArray) and are usually immutable (NSArray) instead of as in other languages where there is not usually a concept of immutable and mutable arrays.
see this SO answer for how to get a "deep copy" of an NSArray.

Resources