NSArray elements from parsed .xml file not accessible on iPhone, using TouchXML - objective-c

I have an NSMutableArray *myArray, wich is the result of a properly .xml parsed file, using TouchXML.
I just want to extract all elements with key name and store then in a separate NSMutableArray, but my final NSMutableArray *namesList is not accessible, crashing my iPhone app right away, because it only contains the last enumerated string and not the whole array.
Here is the code:
NSMutableArray *namesList = [[NSMutableArray alloc] initWithArray:myArray copyItems:YES];
int i;
for (i = 0; i < [myArray count]; i++)
{
namesList = [[myArray objectAtIndex:i] objectForKey:#"name"];
NSLog(#"All Names: %#", namesList);
}
NSLog(#"First Name: %#", [namesList objectAtIndex:0]); <-- crashing line
And here is the NSLog:
-[__NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x6a42540
2012-04-04 10:34:07.882 Sections[3610:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x6a42540'

You should be able to do this:
NSMutableArray * namesList = [NSMutableArray alloc] init];
for(i = 0; i < [myArray count]; i++)
{
NSString * tempString = [NSString stringWithString:[[myArray objectAtIndex:i] objectForKey:#"name"]];
[namesList addobject:tempString];
}
NSLog(#"First Name: %#", [namesList objectAtIndex:0]);

[[myArray objectAtIndex:i] objectForKey:#"name"]; returns an NSString object and not another array therefore you can't send an objectAtIndex to it. Check the structure of your arrays.

Related

[__NSArrayM objectAtIndex:]: index 2 beyond bounds [0 .. 1]'

I want to create an NSArray populating of NSDictionary and print in console the first value of every array's element.
I receive the following error:
Terminating app due to uncaught exception 'NSRangeException',
reason:' -[__NSArrayM objectAtIndex:]: index 2 beyond bounds [0 .. 1]'
* First throw call stack: (0x30d77e83 0x3b0d46c7 0x30cadd95 0xb93b3 0xb8e03 0x3175ccdd 0x30d42e7f 0x30d42a9b 0x30d40e23 0x30cab471
0x30cab253 0x359e52eb 0x33560845 0xb8abd 0x3b5cdab7)
libc++abi.dylib: terminating with uncaught exception of type
NSException
-(void) listOp {
NSDictionary *dictionary;
NSMutableArray *array;
NSNumber *refNum;
int numOp = [_refNum intValue];
self.array = [NSMutableArray arrayWithObjects: self.dictionary, nil];
for ( int i = 0; i < numOp; i++){
[self.array insertObject:self.dictionary atIndex:i];
NSDictionary* vardebug = nil;
vardebug = [self.array objectAtIndex:numOp];
NSString *valuekey = [self.dictionary valueForKey: #"key"];
NSLog(#"Valuekey is: %#", valuekey);
}
}
Don't understand what is going wrong.
Your code is a little bit messy. You declare:
NSDictionary *dictionary;
NSMutableArray *array;
And after that you call
self.dictionary...
self.array...
You use self if you have property, for example;
#property(nonatomic, strong) NSDictionary *dictionary;
so basically if you want to access your:
NSDictionary *dictionary;
NSMutableArray *array;
you should call, for example:
array = [NSMutableArray arrayWithObjects: dictionary, nil];
Without self. But maybe you have both ivar shown in this example and property and you do it by purpose. I just want to say that if you do it by purpose you should use different names just to make your code more clear.
The error you have happened in line:
vardebug = [self.array objectAtIndex:numOp];
In your first loop iteration you have already one item in the array (added during allocation) and you insert another one so you array contains 2 object but you numOp is equal 2 which refer to 3rd object in the array (array are zero base) so the call is beyond bounds. I guess you want to change it to:
vardebug = [self.array objectAtIndex:i];
Hope this help
Replace vardebug = [self.array objectAtIndex:numOp]; by vardebug = [self.array objectAtIndex:i]; should avoid the crash.

How to copy from NSMutableArray to NSMutableString?

Im trying to add some strings into NSMutableArray,than want to copy element 0(zero)
from NSMutableArray to NSMutableString
[MS appendString:str]
this line raises error.
what is the problem ?
a MutableArray element cannot be assigned to NSString ?
(thanks for any responses)
error output is :
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0x6c82440'
here is my code :
NSMutableArray *A=[[NSMutableArray alloc]init];
NSMutableString *MS=[NSMutableString stringWithString:#"first"];
for (int i=0; i<=15;i+=2) {
[A addObject:[NSNumber numberWithInteger:i]];
}
NSString *str;
for (int x=0; x<[A count]; x++) {
str=[A objectAtIndex:0];
[MS appendString:str];//ERROR HERE
}
[A release];
You are adding NSNumbers to the array and not strings n the folioing line:
[A addObject:[NSNumber numberWithInteger:i]]; // here you are adding numbers
So when you read them from the array later, they are still numbers and you have to create strings from them:
NSString *str;
NSNumber *number;
for (int x=0; x<[A count]; x++) {
number = [A objectAtIndex:0]; // You should probably replace 0 by x here.
str = [number stringValue]; // transform number into a string
[MS appendString:str];
}
[A release];
But if you want the array to store strings and not numbers, then replace the first loop instead with the following:
for (int i=0; i<=15;i+=2) {
[A addObject:[[NSNumber numberWithInteger:i] stringValue]];
}
Or
for (int i=0; i<=15;i+=2) {
[A addObject:[NSString stringWithFormat:#"%d", i]];
}

Array index beyond bounds

When I run the code below I get
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]
I understand that at some point in the loop not existed index of the array is reached.
How to deal with that ?
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSArray *t = [NSTimeZone knownTimeZoneNames];
for(id x in t)
{
NSArray *tmpArray = [x componentsSeparatedByString:#"/"];
NSLog(#"%#", [tmpArray objectAtIndex:1]);
}
[pool drain];
return 0;
}
Not all time zones names contain a slash. For example, the UTC time zone name does not contain a slash. So tmpArray might only contain one string, at index 0.
Perhaps this will do what you want:
NSLog(#"%#", [tmpArray lastObject]);
You should check the size of tmpArray first:
NSArray *tmpArray = [x componentsSeparatedByString:#"/"];
if ([tmpArray count] > 1)
NSLog(#"%#", [tmpArray objectAtIndex:1]);
You may want to check the size of tmpArray before accessing index 1

iOS NSComparisonresult issue

It raises an exception when I enter more than two characters in the searchfield. I use NSComparisonResult to show results on a UITableView:
- (void)filterContentForSearchText:(NSString*)searchText
{
for (mystring in self.array)
{
NSComparisonResult result = [mystring compare:searchText options:(NSCaseInsensitiveSearch)
range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame)
{
NSUInteger index=[self.array indexOfObjectIdenticalTo:mystring];
NSUInteger maxindex = index + 50;
for (index ; (index < [self.array count] && index <= maxindex && index!= NSNotFound); index ++)
{
[self.filteredListContent addObject:[NSDictionary dictionaryWithObjectsAndKeys:[self.array objectAtIndex:index],#"english",[self.secondarray objectAtIndex:index],#"translated",nil]];
}
break;
}
}
The output shows:
-[UIDeviceWhiteColor compare:options:range:]: unrecognized selector sent to instance 0x5e4a5d0
2011-11-06 12:10:51.932 XXX[2583:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIDeviceWhiteColor compare:options:range:]: unrecognized selector sent to instance 0x5e4a5d0'
What does UIDeviceWhiteColor in this case mean?
self.array = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"first" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
self.secondarray = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"second" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
That's because there is a UIDeviceWhiteColor somewhere in your self.array, which should be made of just NSStrings. How do you populate this array?
There's a UIDeviceWhiteColor object in self.array. You should also cast mystring as an NSString or whatever kind of object it is. If you'd cast it in UIDeviceWhiteColor then the compiler would give you a warning that UIDeviceWhiteColor does not respond to compare:options:range:.
for (NSString *mystring in self.array)
{
//some code
}

Several Objective-C objects become Invalid for no reason, sometimes

- (void)loadLocations {
NSString *url = #"<URL to a text file>";
NSStringEncoding enc = NSUTF8StringEncoding;
NSString *locationString = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:url] usedEncoding:&enc error:nil];
NSArray *lines = [locationString componentsSeparatedByString:#"\n"];
for (int i=0; i<[lines count]; i++) {
NSString *line = [lines objectAtIndex:i];
NSArray *components = [line componentsSeparatedByString:#", "];
Restaurant *res = [byID objectForKey:[components objectAtIndex:0]];
if (res) {
NSString *resAddress = [components objectAtIndex:3];
NSArray *loc = [NSArray arrayWithObjects:[components objectAtIndex:1], [components objectAtIndex:2]];
[res.locationCoords setObject:loc forKey:resAddress];
}
else {
NSLog([[components objectAtIndex:0] stringByAppendingString:#" res id not found."]);
}
}
}
There are a few weird things happening here. First, at the two lines where the NSArray lines is used, this message is printed to the console-
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFDictionary count]: method sent to an uninitialized mutable dictionary object'
which is strange since lines is definitely not an NSMutableDictionary, definitely is initialized, and because the app doesn't crash.
Also, at random points in the loop, all of the variables that the debugger can see will become Invalid. Local variables, property variables, everything. Then after a couple lines they will go back to their original values. setObject:forKey never has an effect on res.locationCoords, which is an NSMutableDictionary. I'm sure that res, res.locationCoords, and byId are initialized.
I also tried adding a retain or copy to lines, same thing. I'm sure there's a basic memory management principle I'm missing here but I'm at a loss.
Your -[NSArray arrayWithObjects:] call must end with a nil (because a C function needs it to determine how many arguments you gave it).
I don't see anything obviously wrong with memory management here. Maybe add some error checking:
check the error: parameter of initWithContentsOfURL:
check locationString != nil
check lines != nil