NSMutableArray automatically typecasting into NSArray - iphone

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.

Related

how to add object at specified index in NSMutable array?

How can I add object at specified index?
in my problem
NSMutableArray *substring
contains index and object alternatively
and I need to add it to the another array str according to index I getting from this array.
NSMutableArray *str=[NSMutableArray new];
if ([substrings containsObject:#"Category-Sequence:"])
{
NSString *index=[substrings objectAtIndex:5];
//[substrings objectAtIndex:5]
gives me integer position at which I need to add object in `str` array,
gives 5,4,8,2,7,1 etc
NSString *object=[substrings objectAtIndex:1];
//[substrings objectAtIndex:1] gives object,gives NSString type of object
[str insertObject:object atIndex:(index.intValue)];
}
please suggest some way to achieve it.
Thanks in advance!
Allocate the array first & then try to add objects in it.
NSMutableArray *str = [[NSMutableArray alloc]init];
if ([substrings containsObject:#"Category-Sequence:"])
{
NSString *index=[substrings objectAtIndex:5];
NSString *object=[substrings objectAtIndex:1];
[str insertObject:object atIndex:(index.intValue)];
}
Allocate the NSMutableArray before inserting objects into it:
NSMutableArray *strMutableArray = [[NSMutableArray alloc] init];
(You’ll also need to release it when you’re done if you’re not using ARC.)
Or you could also use a temporary object, if you don’t need to keep strMutableArray:
NSMutableArray *strMutableArray = [NSMutableArray array];
Then you can insert objects into the NSMutableArray.
Be careful with using indexes of and in different arrays, however. There might be a better way to do what you want.

Objective c add string object to an array

I've looked everywhere for this, online, on stack overflow and cannot still work out what I'm doing wrong.
I'm trying to add an element to an existing NSMutableArray. But it crashes on line 4:
-[__NSArrayI addObject:]: unrecognized selector sent to instance 0x897b320
The code:
NSMutableArray *mystr = [[NSMutableArray alloc] init];
mystr = [NSArray arrayWithObjects:#"hello",#"world",#"etc",nil];
NSString *obj = #"hiagain";
[mystr addObject:obj];
What am I doing wrong? This is driving me crazy!!!
You array is not mutable!. Use NSMutableArray
mystr = [NSMutableArray arrayWithObjects:#"hello",#"world",#"etc",nil];
You get unrecognized selector since NSArray does not contain the addObject method
Your code should be:
NSMutableArray *mystr = [[NSMutableArray alloc] initWithObjects:#"hello",#"world",#"etc",nil];
NSString *obj = #"hiagain";
[mystr addObject:obj];
The second line you're reassigning an instance of NSArray rather of NSMutableArray to your mystr variable.
Try something like this:
NSMutableArray *mystr = [NSMutableArray arrayWithObjects:#"hello",#"world",#"etc",nil];
[mystr addObject:#"hiagain"]
You originally create mystr as a mutable array, but then assign it to a standard NSArray in the next line. Instead of calling "arrayWithObjects," add each item using "addObjects" or some other function that doesn't create a new immutable array.
Ahhhhh spotted it already
Line 2 should be:
[NSMutableArray arrayWithObjects:#"hello",#"world",#"etc",nil];
Sorry to waste your time with that!

How to copy the contents of NSMutableArray to another NStArray in iphone app?

I have two array one is NSMutableArray and one is NSArray i want to store the contents of NSMutableArray in NSArray but it is not working for me gives exception unrecognised selector sent.
myArray=[[NSArray alloc] initWithArray:appDelegate.surveyAnswersScreenOne];
Note, SurveyAnswerScreenOne is an NSMutableArray
You can do that in many ways -
NSArray * myArray = [appDelegate.surveyAnswersScreenOne copy];
NSArray * myArray = [NSArray arrayWithArray:appDelegate.surveyAnswersScreenOne];
NSArray * myArray = [[NSArray alloc]initWithArray:appDelegate.surveyAnswersScreenOne];
But first of all your appDelegate.surveyAnswersScreenOne should have objects in it.
Have you made object for your appDelegate ?
appDelegate = (yourDelegateClass *)[[UIApplication sharedApplication]delegate];
If yes, then other answers should work!
myArray = [NSArray arrayWithArray:appDelegate.surveyAnswersScreenOne];
From what we see here, it is most likely that your mutable array is nil. Look into the creation of that in you app delegate. If it is created properly, check that it is retained. Is it a strong reference?
#propery(nonatomic, strong) NSMutableArray *surveyAnswersScreenOne;
for one, I would use the convenience method:
myArray = [NSArray arrayWithArray:appDelegate.surveyAnswersScreenOne];
If surveyAnswersScreenOne is a valid array, mutable or otherwise, this should work. Try printing it to the console to be sure. This will return empty array if surveyAnswersScreenOne is nil, where alloc initWithArray will fail.
Check you mutable array like this.
NSLog(#"Mutable array is %#", appDelegate.surveyAnswersScreenOne);

how to split string into NSMutableArray

I want to split string into NSMutableArray
I know
- (NSArray *)componentsSeparatedByString:(NSString *)separator
is available but this one is for NSArray not for NSMutableArray.
I need because after spliting i want to remove element from array by using
-(void)removeObjectAtIndex:(NSUInteger)index
which is not possible with NSArray.
Thank you
You can also just get a mutable copy of the returned array:
NSMutableArray *array = [[myString componentsSeparatedByString:#"..."] mutableCopy];
Also, remember that copy, like alloc, does allocate new memory. So when used in non-ARC code you must autorelease the copied array or manually release it when you are done with it.
Make a new NSMutableArray using
NSArray *array = [NSString componentsSeparatedByString:#"..."];
NSMutableArray *mutable = [NSMutableArray arrayWithArray:array];
Create a NSMutableArray from the output NSArray created by componentsSeparatedByString.
NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithArray:array];

Objective C two-dimensional array memory issues

I'm trying to declare a two-dimensional array as an instance variable in Objective C. I've got the NSMutableArray in the header (data), along with the #property (nonatomic, retain). In viewDidLoad: I have:
data = [[NSMutableArray alloc] init];
[data addObject:[[NSArray alloc] initWithObjects:#"Cheese", #"Meat", #"Veggie", nil]];
[data addObject:[[NSArray alloc] initWithObjects:#"Sandwich", #"Soup", #"Stew", nil]];
I can NSLog the array within the method and it is correct, however when I try to Log it from a separate method I get nothing (just "#"), and if I try to access with
NSInteger num = [[data objectAtIndex:component] count];
it crashes with no error in the log. I'm sure this is something to do with not allocating memory properly, however I am new to Obj C and haven't worked with a C-style language in many years. FWIW, I have tried many variants of this that all fail, including using NSArray instead of mutable, [NSArray arrayWithObjects] instead of [[NSArray alloc] initWithObjects], and every combination in between.
try creating the outer array like this:
self.data = [NSMutableArray arrayWithCapacity:2]; // assuming you're only adding 2 inner arrays.
The following may be a right way.
self.data = [NSMutableArray array];
[data addObject:[NSArray arrayWithObjects:#"Cheese", #"Meat", #"Veggie", nil];
[data addObject:[NSArray arrayWithObjects:#"Sandwich", #"Soup", #"Stew", nil];
Note that, as #jamihash commented above, you need self.data to properly retain the array. And, there is no need to alloc the NSArray which you are adding to data.
As a side issue, you're retaining the child arrays twice. They get retained when you add them to your NSMutableArray, so you should probably autorelease them on creation or create them with one of the NSArray methods that returns an autoreleased array.
Your code by itself shouldn't crash. You should look into where and when you release and retain the NSMutableArray. You could post more of the code and I'm sure somebody will spot the problem.