Passing NSMutableArray from delegate - iphone

I'm doing an Iphone aplication and in the delegate class i call a method from another class which return a NSMutableArray filled with the information i need:
NSMutableArray *array = [[NSMutableArray initWithObjects:nil] retain];
array = [xml loadXML:#"info.xml"];
Now I want to pass this array into the viewController class so i can do things with my mutable array. I do the following:
...
[self.window addSubview:viewController.view];
[self.viewController loadLocations:array];
[self.window makeKeyAndVisible];
In delegate, the array is ok, it has the data i want, however, in the viewController class (which is a UIViewController) the array is messed up.
-(void)loadLocations:(NSMutableArray*)_array{
NSLog(#"%f", [[_array objectAtIndex:0] lat]); // This sould be 42.000 but it is 0.00000 and all of the other indexes

You're in trouble right from the beginning:
NSMutableArray *array = [[array initWithObjects:nil] retain];
You're calling "initWithObjects" on "array", but you haven't allocated "array" yet.
You want something like:
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:nil];
or just :
NSMutableArray *array = [[NSMutableArray alloc] init];

This part is invalid:
NSMutableArray *array = [[array initWithObjects:nil] retain];
array = [xml loadXML:#"info.xml"];
The first line is not used because the second line is setting the array pointer to the result of [xml loadXML:]
I think this should suffice:
NSMutableArray *array = [[NSMutableArray alloc] initWithArray:[xml loadXML:#"info.xml"]];

Related

Issue in adding dynamic cell in table view?

Please have a look on my code which i am using to add dynamic cells in my table view add run time. At did select of my table view i have called this method.
- (void) allServersFound
{
// called from delegate when bonjourservices has listings of machines:
NSArray *newPosts = [[NSArray alloc]initWithObjects:#"A", nil]; // NSArray of machine names;
NSMutableArray *tempArray = [[NSMutableArray alloc] initWithObjects: #"A",#"B",#"C",#"D", nil];
int i = 0;
for (NSArray *count in newPosts)
{
[tempArray addObject:[NSIndexPath indexPathForRow:i++ inSection:0]];
}
[[self tblHome] beginUpdates];
[[self tblHome] insertRowsAtIndexPaths:tempArray withRowAnimation:UITableViewRowAnimationNone];
[[self tblHome] endUpdates];
[tempArray release];
}
But this give me following Exception at run time:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSIndexPath _fastCStringContents:]: unrecognized selector sent to instance 0x4e0e130
First you initialize your tempArray with strings like this:
NSMutableArray *tempArray = [[NSMutableArray alloc] initWithObjects: #"A",#"B",#"C",#"D", nil];
Then you add indexPaths like this:
[tempArray addObject:[NSIndexPath indexPathForRow:i++ inSection:0]];
so the array you pass to the insertRowsAtIndexPaths method contains both strings and indexPaths objects. I think this is the reason of the exception.
As others noted, your tempArray contains a mixture of NSString and NSIndexPath objects. This is the most obvious thing that you need to address before you do anything else. You can use [NSMutableArray array] class method for that (it's autoreleased, so you'll need to remove the call to [tempArray release] at the end of your method).
A less obvious thing is that the model of your UITableView must be updated before you call insertRowsAtIndexPaths, otherwise you would get another exception in a much less obvious place.
Your tmparray contains NSString values as well as the IndexPaths, try removing the NSStrings first.
Try replacing the line
NSMutableArray *tempArray = [[NSMutableArray alloc] initWithObjects: #"A",#"B",#"C",#"D", nil];
with the line
NSMutableArray *tempArray = [[NSMutableArray alloc] initWithObjects:nil];

Getting out a undefined number of ViewController from an Array

In my app, I load UIViewController into an array from a .plist, and then, I need to get those VC's out. The problem is, since the number of VC's is not always the same, then I don't know how many I'm getting out each time. So I'm looking for a better engeneered solution - better iteration, rather than hard coding.
For example:
NSMutableArray *views = [[NSMutableArray alloc] init];
for (int i = [currentList count]; i > 0; i--) {
UIViewController *view = [[UIViewController alloc] init];
view.title = [NSString stringWithFormat:#"dgdg - %i", i];
[views addObject:view];
}
So there is my array of VC's, and now:
myIvar = [[CustomSubClass alloc] initWithViewControllers:**help** nil];
I tried:
myIvar = [[CustomSubClass alloc] initWithViewControllers:[views copy], nil];
and:
myIvar = [[CustomSubClass alloc] initWithViewControllers:[NSIndexSet..., nil];
I tried:
myIvar = [[CustomSubClass alloc] initWithViewControllers:[views objectAtIndex:0]... nil];
but none of it worked. Thanks in advance.
The syntax you want is like this:
[[CustomSubClass alloc] initWithViewControllers:[views objectAtIndex:0], [views objectAtIndex:1], [views objectAtIndex:2], nil];
Basically just repeat have all your arguments separated by commas, then always have the final argument be nil.
views is an array and you can pass this directly as a parameter like so:
 myIvar = [[CustomSubClass alloc] initWithViewControllers:views];

Array in UITextView

I have an arrayappdeligate.biblearray. I just want to display this array in a textview. This array contains sql datas of 4 types chapterno, verses, genisis and text. i need to extract only the verses and display it in textview how to do this?
It seems biblearray has the objects of type bible. You can get the verses from bible objects like this,
bible *_bible = (bible *)[appDelegate.bibleArray objectAtIndex:0];
textView.text = [_bible verses];
or directly as,
textView.text = [[appDelegate.bibleArray objectAtIndex:0] verses];
If you want to display all the verses in the textView, you can do it like this,
NSArray *allVerses = [appDelegate.bibleArray valueForKey:#"verses"];
textView.text = [allVerses componentsJoinedByString:#"\n\n"];
#"\n\n" adds two new lines between the verses.
You need to do some alteration. Create NSDisctionary instead.
Take a dictionary where you are adding data from database
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
NSMutableArray *chapterno = [[NSMutableArray alloc]init];
NSMutableArray *verses = [[NSMutableArray alloc]init];
NSMutableArray *genisis = [[NSMutableArray alloc]init];
NSMutableArray *text = [[NSMutableArray alloc]init];
//Add data you are getting from database
[chapterno addObject:chapternodata];
[verses addObject:versesdata];
[genisis addObject:genisisdata];
[text addObject:textdata];
[dict setValue:chapterno forKey:#"chapterno"];
[dict setValue:verses forKey:#"verses"];
[dict setValue:genisis forKey:#"genisis"];
[dict setValue:text forKey:#"text"];
[chapterno release];
[verses release];
[genisis release];
[text release];
Take one NSDictionary in AppDelegate say appDict and make it equal to dict
NSMutableArray *arrVerses = [[objAppDel.appDict objectForKey:#"verses"];
txt.text = [arrVerses description];

problem while getting arrays from one class to another class

i am have 4 arrays in myclass.m
i need to get those arrays into myclassviewcontroller.m
for that i write code in myclassviewcontroller.m like this.
- (void)resultarrays :(NSMutableArray *)Agentids loanofficerid:(NSMutableArray *)Loanofficerid agentname:(NSMutableArray *)agentname agentemail:(NSMutableArray *)agentemail agentphone:(NSMutableArray *)Agentphone {
agentids = [[NSMutableArray alloc] initWithObjects:Agentids,nil];
loanofficerid = [[NSMutableArray alloc] initWithObjects:Loanofficerid,nil];
agentnames = [[NSMutableArray alloc] initWithObjects:agentname,nil];
agentemails = [[NSMutableArray alloc] initWithObjects:agentemail,nil];
agentphone = [[NSMutableArray alloc] initWithObjects:Agentphone,nil];
NSLog(#"123 %#",agentids);
NSLog(#"123 %#",loanofficerid);
NSLog(#"123 %#",agentnames);
NSLog(#"123 %#",agentphone);
}
in myclass.m i write this
myclassviewcontroller *LOVobj = [[myclassviewcontroller alloc]init];
[LOVobj resultarrays:resultData_agent loanofficerid:array1 agentname:array2 agentemail:array3 agentphone:array4];
then it displays all the objects that i print in console.
After this, In the button click i print these arrays then it prints null.
even i assign setter and getter methods to it.
i did n't what's the problem can any one please help me.
Thank u in advance.
First of all, change the code to this:
- (void)resultarrays :(NSArray *)Agentids loanofficerid:(NSArray *)Loanofficerid agentname:(NSArray *)agentname agentemail:(NSArray *)agentemail agentphone:(NSArray *)Agentphone {
agentids = [[NSMutableArray alloc] initWithArray: Agentids];
loanofficerid = [[NSMutableArray alloc] initWithArray: Loanofficerid];
agentnames = [[NSMutableArray alloc] initWithArray: agentname];
agentemails = [[NSMutableArray alloc] initWithArray: agentemail];
agentphone = [[NSMutableArray alloc] initWithArray: Agentphone];
NSLog(#"123 %#",agentids);
NSLog(#"123 %#",loanofficerid);
NSLog(#"123 %#",agentnames);
NSLog(#"123 %#",agentphone);
}
Don't pass mutable array if you don't want it to change.
First of all, you're creating arrays containing references to arrays, not arrays of the objects in the parameter arrays. And since you're storing the references of the parameter arrays, if the contents of the parameter arrays changes, so will all the references.
You probably instead want something like this for each array:
agentids = [NSMutableArray arrayWithArray: Agentids];
(and [agentids retain] since arrayWithArray returns an auto-released object).

NSArray runtime array

I have got I have got two methods both in different classes. One is class method and other is instance method. i am calling class method from instance method. When instance method finishes it gives runtime error "EXC_BAD_ACCESS".
#import "xmlObject.h"
#import "textmeAppDelegate.h"
#implementation Class1
- (void)method1 {
textmeAppDelegate *del = (textmeAppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *bgColor = [[NSArray alloc] initWithArray:[xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:#"backgroundcolor"]]];
UIColor *color = [UIColor colorWithRed:[[bgColor objectAtIndex:3] floatValue] green:[[bgColor objectAtIndex:2] floatValue] blue:[[bgColor objectAtIndex:1] floatValue] alpha:[[bgColor objectAtIndex:0] floatValue]];
CGContextSetFillColor(context, CGColorGetComponents([color CGColor]));
CGContextFillRect(context, rect);
[bgColor release];
}
#end
#implementation xmlObject
+ (NSArray *) fetchImmediateChildrenValues:(NSMutableDictionary *) node {
NSMutableDictionary *tmp = [[node objectForKey:#"children"] retain];
NSArray *keys = [[NSArray alloc] initWithArray:[tmp allKeys]];
keys = [keys sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
NSMutableArray *pushArr = [[[NSMutableArray alloc] init] autorelease];
NSString *val = [[NSString alloc] init];
for(NSString *str in keys) {
val = (NSString *)[[tmp objectForKey:str] objectForKey:#"innertext"];
[pushArr addObject:val];
}
[val release];
[keys release];
return [NSArray arrayWithArray:pushArr];
}
#end
What is wrong with the code? Also app is crashing for this line of code
application is crashing if i include this line
NSArray *bgColor = [[NSArray alloc] initWithArray:[xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:#"backgroundcolor"]]];
If I remove it application runs smoothly.
I have several comments on your code. One of them is the immediate cause of your crash, but you need to fix at least one other issue too. The short answer is that you over release val and keys.
NSArray *bgColor = [[NSArray alloc] initWithArray:[xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:#"backgroundcolor"]]];
You don't need to create a new array here, you can simply write the following:
NSArray *bgColor = [xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:#"backgroundcolor"]];
if you do, you don't need the [bgColor release] further down.
NSArray *keys = [[NSArray alloc] initWithArray:[tmp allKeys]];
keys = [keys sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
These two lines leak the first NSArray, you alloc it but you overwrite it straight away with the sorted version. In fact, you can simply write:
keys = [[tmp allKeys] sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
Note that you do not own keys so you can get rid of the [keys release] line further down.
NSString *val = [[NSString alloc] init];
for(NSString *str in keys) {
val = (NSString *)[[tmp objectForKey:str] objectForKey:#"innertext"];
[pushArr addObject:val];
}
[val release];
This is the source of your immediate problem. You first alloc a new string. Then you immediately overwrite it on each iteration of your loop. So the allocated NSString leaks. You do not own the val returned by [[tmp objectForKey:str] objectForKey:#"innertext"]; on each iteration, so the release ov val after the loop should not be there.
On a side note, objectForKey: returns an id - the cast to NSString* is redundant. Most people leave it out.
[keys release];
Going back to the bit above where I told you that you were leaking your alloc'd keys? Well the new version of keys you overwrote it with you don't own. Therefore you must not release keys here.
return [NSArray arrayWithArray:pushArr];
This is fine. My preference would be for:
return [[pushArray copy] autorelease];
but it is just a matter of style. You could also just return pushArray, but pushArray is mutable and the caller may rely on the return value being immutable.
Test your code with NSZombieEnabled set... It should give you enough informations to fix your problem.