NSMutableArray *experienceValues;
experienceValues = [NSMutableArray alloc] initWithObjects:0,83,174,276,nil];
NSLog(#"%#", [experienceValues objectAtIndex:3]);
Why does this always throw -[__NSArrayM objectAtIndex:]: index 3 beyond bounds for empty array when it is clearly allocated and initialised in the line just before?
You need to wrap integer values like #0, #83, #174, ..., as primitive integers are no objects.
The NSMutableArray class as most of the collection classes in cocoa, accepts only objects. So if you want to put numbers, you can't put primitive type, but only instances of NSNumber class, thus:
[[NSMutableArray alloc] initWithObjects:[NSNumber numberWithInt:0]...etc
Or with literals:
[[NSMutableArray alloc] initWithObjects:#0,#83,#174,#276.. etc
The array is empty because the arguments are nil terminated and 0 is interpreted as nil.
The array should only contain objects (as opposed to primitives like ints). In you case you should create NSNumbers for all the numbers. You can do that with the number literal syntax #2.0.
Objective-C collection classes can only store objects; not primitives like int.
You need to wrap them in NSNumber objects.
If these are literal values then the answer provided by #Kirsteins demonstrates the syntax.
Try this
NSMutableArray *experienceValues = [[NSMutableArray alloc] initWithObjects:#0,#83,#174,#276,......., nil];
NSLog(#"%d", [experienceValues objectAtIndex:3]);
As initWithObjects: accepts only object you need to put only objects in it
You're trying to add integer value to NSArray.
NSMutableArray *experienceValues = [[NSMutableArray alloc] initWithObjects:[NSNumber numberWithInteger:42],nil];
then convert it back to integer like,
NSLog(#"%#", [experienceValues objectAtIndex:0]);
Related
NSArray and NSMutableArray's +arrayWithArray: returns empty array instead of nil when argument is nil.
NSLog(#"%#", [[NSArray arrayWithArray:nil] class]);
NSLog(#"%#", [[NSMutableArray arrayWithArray:nil] class]);
output:
__NSArrayI
__NSArrayM
But this behavior is not documented on Apples documentation.
Is it safe to rely on the assumption that arrayWithArray:nil returns empty array?
Or should I assign empty array explicitly like this:
NSDictionary *dic = [[NSDictionary alloc] init];
NSMutableArray *arr = [dic objectForKey:#"a"];
if (!arr) {
arr = [[NSMutableArray alloc] init];
}
The documentation of +arrayWithArray: says:
Creates and returns an array containing the objects in another given
array.
Of course, nil is not an array, but [nil count] is valid and returns 0, so it might be treated as an empty array here.
But I would not rely on that fact and create empty arrays with [[NSMutableArray alloc] init] or [NSMutableArray array].
ADDED:
If you call +arrayWithArray: with an invalid type, e.g. a NSString, then of course the program will throw an exception. But from the error message
-[__NSCFConstantString count]: unrecognized selector sent to instance 0x69e4
you can see that count is indeed the first method used to copy the array elements. That also explains why it works with nil.
I created an NSMutableArray object by
NSMutableArray *array = [[NSMutableArray alloc]init];
and used method componentsSeperatedByString: as
array = [myString componentsSeperatedByString:#"++"];
but when I performed operation on array like,
[array removeAllObjects];
I got exception like "removeAllObjects unrecognized selector send to instance".
I solved this issue by modifying code like,
NSArray *components = [myString componentsSeperatedByString:#"++"];
array = [NSMutableArray arrayWithArray:components];
and I after that could perform operation like
[array removeAllObjects];
My doubt is why did NSMutableArray automaticaqlly converted to NSArray? How Can I avoid automatic type conversion like this, to prevent exceptions? Thanks in advance....
There is a mistake in your understanding of how Objective-C works. This line:
NSMutableArray *array = [[NSMutableArray alloc]init];
allocates and initializes the array, and the pointer array points to this object. Now, this line:
array = [myString componentsSeperatedByString:#"++"];
makes the array pointer to point to the new array returned by componentsSeparatedByString method. You loose the reference to your alloced and inited mutable array when you do this, and you create the memory leak if you don't use ARC.
This is happening because [myString componentsSeperatedByString:#"++"] returns an NSArray. You can try something like this:
array = [[myString componentsSeperatedByString:#"++"] mutableCopy];
or
array = [NSMutableArray arrayWithArray:[myString componentsSeperatedByString:#"++"]];
This is because – componentsSeparatedByString: returns a NSArray: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/componentsSeparatedByString:
Do something like:
array = [NSMutableArray arrayWithArray:[myString componentsSeperatedByString:#"++"]];
On the line
array = [myString componentsSeperatedByString:#"++"];
you are replacing the NSMutableArray you allocated with a new NSArray (and leaking your NSMutableArray. Try using this:
NSMutableArray *array = [NSMutableArray arrayWithArray:[myString componentsSeperatedByString:#"++"]];
It's not converted, the array pointer could be UIButton* if you write something like
array = [self likeThatButton];
where likeThatButton is your method returning UIButton*. As always in objective c, NSMutableArray *array means only the Xcode will try to analyze your code and suggest convenient warnings and code completion.
An NSMutableArray instance won't be converted automatically.
The method componentsSeperatedByString returns an NSArray-Object. You should get a compiler warning when assigning the return-value to a NSMutableArray-Pointer.
I am using one NSMutableArray with same string object.
Here is the code
NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:#"hello",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",nil];
NSObject *obj = [arr objectAtIndex:2];
[arr removeObject:obj];
NSLog(#"%#",arr);
When i try to remove 3rd object of array, its removing all object with "hi" string.
I am not getting why its happening.
my doubt is while removing object, NSMutableArray match string or address.
It's because you're using removeObject which removes all objects that are "equal" to the one you pass in. As per this Apple documentation:
This method uses indexOfObject: to locate matches and then removes
them by using removeObjectAtIndex:. Thus, matches are determined on
the basis of an object’s response to the isEqual: message. If the
array does not contain anObject, the method has no effect (although it
does incur the overhead of searching the contents).
You're seeing the effects of literal strings here where each of those #"hi" objects will turn out to be the same object just added many times.
What you really want to do is this:
NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:#"hello",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",nil];
[arr removeObjectAtIndex:2];
NSLog(#"%#",arr);
Then you're specifically removing the object at index 2.
According to https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html
removeObject:
Removes all occurrences in the array of a given object.
which is exactly the behaviour you're seeing. If you want to remove the object at a particular position, you want removeObjectAtIndex:.
NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:#"hello",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",#"hi",nil];
NSUInteger obj = [arr indexOfObject:#"hi"]; //Returns the lowest integer of the specified object
[arr removeObjectAtIndex:obj]; //removes the object from the array
NSLog(#"%#",arr);
I need to copy the contents of an NSArray to NSMutable array. In other words, I want to copy arrayCountryChoices to arraySearchResults. Any ideas????
//main data
NSArray *arrayCountryChoices;
//search results buffer
NSMutableArray *arraySearchResults;
//create data
arrayCountryChoices = [[NSArray alloc] initWithObjects:#"foo",#"bar",#"baz",nil];
//copy the original array to searchable array ->> THIS IS NOT WORKING AS EXPECTED
arraySearchResults = [[NSMutableArray alloc] arrayWithArray:arrayCountryChoices];
Thanks in advance.
it's either
[NSMutableArray arrayWithArray:anArray];
or
[[NSMutableArray alloc] initWithArray:anArray];
or
[anArray mutableCopy];
The code in your example doesn't work because you're calling arrayWithArray on an instance of NSMutableArray, but arrayWithArray is a class method.
As a general rule, initalization methods that start with init are instance methods, and those that start with the name of the class (array, etc.) are class methods. Class methods return autoreleased objects, while instance methods return retained objects.
You can also create empty mutable array and add objects to it using -addObjectsFromArray method
Please note that when using:
[NSMutableArray arrayWithArray:anArray];
or
[[NSMutableArray alloc] initWithArray:anArray];
you'll always get an array even if anArray was nil, but with:
[anArray mutableCopy];
you'll get nil if anArray is nil. So if you want to be sure that you actually get an array even if it may be empty, use one the former methods.
It's not working because arrayWithArray is a class method, not an instance method.
You can do [NSMutableArray arrayWithArray:arrayCountryChoices] to do what you need.
You could just call [arrayCountryChoices mutableCopy] to return a new mutable array with the contents of arrayCountryChoices.
I'm new to Objective-C and iPhone development, and I'm trying to store floating-point values in an NSMutableArray, but when I do I get an error saying "incompatible type for argument 1 of 'addObject". What am I doing wrong? I'm trying to create an array of doubles that I can perform math calculations with.
NSMutableArray only holds objects, so you want an array to be loaded with NSNumber objects.
Create each NSNumber to hold your double then add it to your array. Perhaps something like this.
NSMutableArray *array = [[NSMutableArray alloc] init];
NSNumber *num = [NSNumber numberWithFloat:10.0f];
[array addObject:num];
Repeat as needed.
Use an NSNumber to wrap your float, because the dictionary needs an object:
[myDictionary setObject:[NSNumber numberWithFloat:0.2f] forKey:#"theFloat"];
/* or */
[myDictionary setObject:#0.2f forKey:#"theFloat"];
retrieve it by sending floatValue:
float theFloat = [[myDictionary objectForKey:#"theFloat"] floatValue];
Code is untested.
You can wrap many other data types in NSNumber too, check the documentation. There's also NSValue for some structures like NSPoint and NSRect.
In Cocoa, the NSMutableDictionary (and all the collections, really) require objects as values, so you can't simply pass any other data type. As both sjmulder and Ryan suggested, you can wrap your scalar values in instances of NSNumber (for number) and NSValue for other objects.
If you're representing a decimal number, for something like a price, I would suggest also looking at and using NSDecimalNumber. You can then avoid floating point inaccuracy issues, and you can generally use and store the "value" as an NSDecimalNumber instead of representing it with a primitive in code.
For example:
// somewhere
NSDecimalNumber* price = [[NSDecimalNumber decimalNumberWithString:#"3.50"] retain];
NSMutableArray* prices= [[NSMutableArray array] retain];
// ...
[prices addObject:price];
NSMutableArray *muArray = [[NSMutableArray alloc] init];
NSNumber *float = [NSNumber numberWithFloat:210.0f];
NSNumber *float1 = [NSNumber numberWithFloat:211.0f];
[muArray addObject:float];
[muArray addObject:float1];
NSlog(#"my array is--%#",muArray);