I were reading another programmer's code, so i found this:
#property(nonatomic, strong) NSArray *assets;
----
_assets = [#[] mutableCopy];
__block NSMutableArray *tmpAssets = [#[] mutableCopy];
Is it some kind of trick? Why does he used mutableCopy to immutable array assets ? Why doesn't he just create it like:
self.assets = [NSArray new];
__block NSMutableArray *tmpAssets = [NSMutableArray new];
?
Just a shorthand to get an empty mutable array.
Instead of [NSMutableArray alloc] init] it's slightly less code to write -
the new construct isn't really used by the majority of Objective-C programmers and was added as a convenience to newcomers from other languages.
Mind that #[] will create an (immutable) NSArray -
there is no Objective-C literal for NSMutableArray.
Related
How to addObject to NSArray using this code? I got this error message when trying to do it.
NSArray *shoppingList = #[#"Eggs", #"Milk"];
NSString *flour = #"Flour";
[shoppingList addObject:flour];
shoppingList += #["Baking Powder"]
Error message
/Users/xxxxx/Documents/iOS/xxxxx/main.m:54:23: No visible #interface for 'NSArray' declares the selector 'addObject:'
addObject works on NSMutableArray, not on NSArray, which is immutable.
If you have control over the array that you create, make shoppingList NSMutableArray:
NSMutableArray *shoppingList = [#[#"Eggs", #"Milk"] mutableCopy];
[shoppingList addObject:flour]; // Works with NSMutableArray
Otherwise, use less efficient
shoppingList = [shoppingList arrayByAddingObject:flour]; // Makes a copy
You can't add objects into NSArray. Use NSMutableArray instead :)
Your array cant be changed because is defined as NSArray which is inmutable (you can't add or remove elements) Convert it to a NSMutableArray using this
NSMutableArray *mutableShoppingList = [NSMutableArray arrayWithArray:shoppingList];
Then you can do
[mutableShoppingList addObject:flour];
NSArray does not have addObject: method, for this you have to use
NSMutableArray. NSMutableArray is used to create dynamic array.
NSArray *shoppingList = #[#"Eggs", #"Milk"];
NSString *flour = #"Flour";
NSMutableArray *mutableShoppingList = [NSMutableArray arrayWithArray: shoppingList];
[mutableShoppingList addObject:flour];
Or
NSMutableArray *shoppingList = [NSMutableArray arrayWithObjects:#"Eggs", #"Milk",nil];
NSString *flour = #"Flour";
[shoppingList addObject:flour];
I'm a little confused about NSArray initialization. The confusing thing is we have different init methods to init it, and if I just init it without giving any size and any objects, how compiler knows it object count or size in RAM.
What's the logic/difference behind init method? Can anybody explain it briefly?
Edit:
NSArray *sortedArray = [[NSArray alloc] init];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"quota" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:descriptor];
//How is that possible to modifying to immutable object
sortedArray = [sortedContainers sortedArrayUsingDescriptors:sortDescriptors];
I know the differences between NSArray and NSMutableArray and I'm not looking for the differences. I just wonder how that code can compile/execute without an error.
[[NSArray alloc] init] returns an empty, immutable array. There's nothing surprising about that. What else would you return from a method to mean "no items?"
how compiler knows it object count or size in RAM
The object count is 0. It's empty. Its size in RAM is the size of an empty NSArray. NSArray is an object, so it has some standard objc_object overhead, plus some instance variables for NSArray.
That said, as an implementation detail, Cocoa optimizes this out and always returns the same singleton for all empty NSArray objects. You can demonstrate this with:
NSArray *a = [[NSArray alloc] init];
NSArray *b = [[NSArray alloc] init];
NSLog(#"%p", a);
NSLog(#"%p", b);
if (a == b) { // Pointer equality, not isEqual:
NSLog(#"Same object");
}
So, what is this doing?
NSArray *sortedArray = [[NSArray alloc] init]; // (1)
// ... code that doesn't matter ...
sortedArray = [sortedContainers sortedArrayUsingDescriptors:sortDescriptors]; // (2)
At line 1, you're creating a local pointer variable, sortedArray and pointing it to an empty array (it happens to be a singleton, but that's an optimization detail).
At line 2, you create a completely different NSArray by calling sortedArrayUsingDescriptors:. You then point sortedArray at that object. ARC sees that you're no longer pointing at the empty array, and releases it. (Again, optimization details jump in here and the actual steps may be different, but the effect will be the same.)
The correct code here would be:
// ... Code that sets up sortDescriptors ...
NSArray *sortedArray = [sortedContainers sortedArrayUsingDescriptors:sortDescriptors];
Now, in very modern ObjC, you won't see [[NSArray alloc] init] written out very often. It's easier to write #[] (which is really just syntactic sugar for a method call). But before array literals were added to language, [[NSArray alloc] init] or [NSArray array] were reasonably common.
If you just init NSArray without giving any size and any objects it will remain empty during lifetime. NSArray is immutable
If your question is about NSMutableArray, read here at the SO
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];
Why can't I stick NSString[] into NSArray? I get the following error "Implicit conversion of an indirect pointer to an Objective-C pointer to 'id' is disallowed with ARC"
Here's the code:
NSString *s1, *s2;
NSString *cArray[]={s1, s2};
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
[dataArray addObject:cArray];
You cannot do it, because the ownership of cArray cannot be transferred.
If it is a local variable, it would disappear as soon as its scope ends, leaving your mutable array with a dangling reference.
Even if it is a global, there would be a problem, because your NSMutableArray would not know how to release the C array properly.
Objective C wants to protect you from situations like that as much as possible, providing nice classes such NSArray to make your job easier:
NSMutableArray *dataArray = [NSMutableArray array];
NSString *s1 = #"hello", *s2 = #"world";
// You can choose another constructor as you see fit.
NSArray *cArray = #[s1, s2];
[dataArray addObject:cArray];
NSArray holds objects. A C array is not an object, so you can't put it in an NSArray. If you want to create an NSArray out of a C array, you can use the arrayWithObjects:count: constructor.
I am making the switch from Java to Objective-c, and I'm having some difficulty. I have searched this problem this without much success.
I have an NSMutableArray that stores NSMutableArrays. How do I add an array to the array?
You can either store a reference to another array (or any type of object) in your array:
[myArray addObject:otherArray];
Or concatenate the arrays.
[myArray addObjectsFromArray:otherArray];
Both of which are documented in the documentation.
Since an array is just an object like any other:
[myContainerMutableArray addObject:someOtherArray];
Or if you want to concatenate them:
[myFirstMutableArray addObjectsFromArray:otherArray];
You add it like any other object.
NSMutableArray *innerArray = [NSMutableArray array];
NSMutableArray *outerArray = [NSMutableArray array];
[outerArray addObject:innerArray];
In case if you add the same NSMutableArray Object, Like
NSMutableArray *mutableArray1 = [[NSMutableArray alloc]initWithObjects:#"test1",#"test2",#"test3",nil];
NSMutableArray *mutableArray2 = [[NSMutableArray alloc]initWithObjects:#"test4",#"test5",#"test6", nil];
mutableArray1 = [NSMutableArray arrayWithArray:mutableArray1];
[mutableArray1 addObjectsFromArray:mutableArray2];
Nslog(#"mutableArray1 : %#",mutableArray1);
[YourArray addObjectsFromArray:OtherArray];