I have been trying to work through a bug for many hours in my iOS App involving rangeOfString and have finally been able to track down where my app crashes. My app sets TextViewA to the first half of my MainTextView. What if statement should be added should be added to check for nil?
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSCFString rangeOfString:options:range:locale:]: nil argument'
*** First throw call stack:
.
[[myViewController tvTextFirstHalf] setText:[[mainTextView.text componentsSeparatedByString:[[myViewController tvTextMiddle]text]] objectAtIndex:0]];
..............................................................................................
No memory available to program now: unsafe to call malloc
2013-01-04 14:30:58.138 Type[7279:c07] separator: (null)
2013-01-04 14:30:58.138 Type[7279:c07] mainTextView: ; layer = ; contentOffset: {0, 0}
>
2013-01-04 14:30:58.139 Type[7279:c07] mainTextView.text: TESTTTTTTTT f f.
2013-01-04 14:30:58.142 Type[7279:c07] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSCFString rangeOfString:options:range:locale:]: nil argument'
* First throw call stack:
(0x1a5d012 0x1882e7e 0x1a5cdeb 0xf78688 0xf87d88 0xfd05df 0x165ec 0x15dc6 0x1fd7b 0x56d8d5 0x56db3d 0xf74e83 0x1a1c376 0x1a1be06 0x1a03a82 0x1a02f44 0x1a02e1b 0x221d7e3 0x221d668 0x4be65c 0x2c5d 0x2b85)
libc++abi.dylib: terminate called throwing an exception
(gdb)
This oneliners are not considered a good practice in obj-C (i know, it's arguable).
Try to break:
[[myViewController tvTextFirstHalf] setText:[[mainTextView.text componentsSeparatedByString:[[myViewController tvTextMiddle]text]] objectAtIndex:0]];
Into some more debugging-friendly code:
NSString *separator = [[myViewController tvTextMiddle]text];
NSLog (#"separator: %#", separator);
NSLog (#"mainTextView: %#",mainTextView); //is this one nil?
NSLog (#"myViewController.tvTextMiddle: %#", myViewController.tvTextMiddle); //what about this one??
NSLog (#"mainTextView.text: %#",mainTextView.text);
NSArray *components = [mainTextView.text componentsSeparatedByString:separator];
NSLog (#"we found %d components", components.count);
NSString *result = (NSString *)[components objectAtIndex:0];
NSLog (#"result should be: %#", result);
[[myViewController tvTextFirstHalf] setText:result];
The code will break ofcourse but at least you'll know where the problem lies.
You could change last four lines then in something like:
if (components.count >= 1)
{
NSString *result = (NSString *)[components objectAtIndex:0];
NSLog (#"result should be: %#", result);
[[myViewController tvTextFirstHalf] setText:result];
}
else
{
[[myViewController tvTextFirstHalf] setText:#"empty!"];
}
EDIT:
From the NSLog you posted it is obvious that your separator [[myViewController tvTextMiddle]text] is null. Note that null is not the same as empty string. It is unallocated string.
My guess is that actually your tvTextMiddle is null (or if you are using XIB files it is not properly connected to the IBOutlet).
You can check that by adding (somewhere before the breaking-line):
NSLog (#"myViewController.tvTextMiddle: %#", myViewController.tvTextMiddle);
The crash is due to this call componentsSeparatedByString.
If your textview is nil or no text then crash'll occur.
So add a condition like:
if(mainTextView.text.length != 0 && [myViewController tvTextMiddle]text].length != 0)
{
[[myViewController tvTextFirstHalf] setText:[[mainTextView.text componentsSeparatedByString:[[myViewController tvTextMiddle]text]] objectAtIndex:0]];
}
Related
Whenever I insert an NSString return from a view into the UITableView's data source, when the call to insert the new cell is placed, the program crashes. Below is the code:
- (void)insertTableObject:(NSString *)thing
{
if (!locations) locations = [[NSMutableArray alloc] init];
[locations addObject:[NSString stringWithFormat:#"%#", thing]];
NSLog(#"%#", locations);
self.tableContents = [[NSMutableDictionary alloc] initWithObjectsAndKeys:locations,#"", nil];
self.sortedKeys =[[self.tableContents allKeys] sortedArrayUsingSelector:#selector(compare:)];
[self.tableView insertRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:([locations count]-1) inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
}
Below is the array printed out, and the accompanying error that takes place:
2013-03-23 15:06:32.433 XXX[9149:907] (
"D.C",
la
)
2013-03-23 15:06:32.439 XXX[9149:907] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(0x320852a3 0x39f1b97f 0x31fd0b75 0xc05bd 0x33ed854d 0x33ec9685 0x33ec5d55 0x33ec4d27 0x33ec1bf9 0x33ff6b27 0xbeceb 0xf6413 0x33f780c5 0x33f78077 0x33f78055 0x33f7790b 0x33f77e01 0x33ea05f1 0x33e8d801 0x33e8d11b 0x35b815a3 0x35b811d3 0x3205a173 0x3205a117 0x32058f99 0x31fcbebd 0x31fcbd49 0x35b802eb 0x33ee1301 0xb701b 0xb6f70)
libc++abi.dylib: terminate called throwing an exception
Is it a problem that "la" is printing without quotes? Could the system potentially not be seeing that entry?
I ended up solving the problem. I had cells with detail views, so when it would draw the detailView index, it wasn't present. I added a simple line to the function in the original post to add another value to the detailView array.
Im having truble adding objects to my 2 NSMutableArrays. The data comes from a database and I know that my parsing is correct because I get valid outputs when I use the NSLog. However I can't figur out how to add the 2 different objects to my 2 different NSMutableArrays. Here is my code
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
allDataDictionary = [NSJSONSerialization JSONObjectWithData:webData options:0 error:nil];
feed = [allDataDictionary objectForKey:#"feed"];
arrayOfEntry = [feed objectForKey:#"entry"];
for (NSDictionary *dictionary in arrayOfEntry) {
NSDictionary *title = [dictionary objectForKey:#"title"];
NSString *labelTitle = [title objectForKey:#"label"];
[arrayLabel addObject:labelTitle];
NSDictionary *summary = [dictionary objectForKey:#"summary"];
NSString *labelSummary = [summary objectForKey:#"label"];
[arraySummary addObject:labelSummary]; //This line makes the application crash
}
}
for some reason when I want to add labelSummary to arraySummary I get this error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
Any help is appreciated.
Your parsing is indeed correct. However, when the parser comes across an empty field it returns nil. The problem is the that NSArrays cannot accept nils, because nil is not an object, it's equivalent to 0. Therefore, you most add an object. This the role of NSNull.
Must test to see if the parser returns nil, and if so add [NSNull null].
NSString* labelSummary = [summary objectForKey:#"label"];
[arraySummary addObject:(labelSummary!=nil)?labelSummary:[NSNull null];
The error message tells you that one of the objects you are trying to add to the array is nil.
You have to replace
[arrayLabel addObject:labelTitle];
with
if (labelTitle != nil) {
[arrayLabel addObject:labelTitle];
}
and
[arraySummary addObject:labelSummary];
with
if (labelSummary != nil) {
[arraySummary addObject:labelSummary];
}
If you really need to include a nil object, then use NSNull.
I have this in a class:
NSString *globalMidiData = #"30a0a00\n";
switch (IndicatorCheckNXT) {
case 1:
[testRobot checkTestRobot:globalMidiData];
break;
default:
break;
}
And in another class I have this:
-(void) checkTestRobot: (NSString *)midiDataGlobal{
bool pressed;
bool pressed2;
NSString *miawmiaw =[NSString alloc];
miawmiaw=midiDataGlobal;
}
And I got this message:
-[AppDelegate checkTestRobot:]: unrecognized selector sent to instance 0x18acb0
2012-11-23 20:45:31.755 Exemple1[477:707] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AppDelegate checkTestRobot:]: unrecognized selector sent to instance 0x18acb0'
What I am doing wrong?
Obviously you send checkTestRobot to the wrong object. testRobot seems to point to the AppDelegate and not to an instance of your class.
Also you should replace this:
NSString *miawmiaw =[NSString alloc];
miawmiaw=midiDataGlobal;
with:
NSString *miawmiaw = [midiDataGlobal copy];
I have 7 CCLabelAtlas labels declared in .h file like this CCLabelAtlas *numberStat[7]. Then I then initialized them in a for loop in .m file:
for (int i = 1; i <=7; i++) {
NSString* statName = [NSString stringWithFormat #"Number %d", i];
numberStat[i] = [[CCLabelAtlas labelWithString: [self loadThisValue:statName] charMapFile:#"digitalNumbers.png" itemWidth:26 itemHeight:37 startCharMap:'0'] retain];
[self addChild: numberStat[i]];
}
The problem comes when I try to update the label. I can update from 2 to 7 just fine, but when I try to update numberStat[1]'s string (numberStat[1].string = #"111";), it crashes. The exact same code works for 2-7.
Here's the crash log:
-[CCSprite setString:]: unrecognized selector sent to instance 0x897cbd0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CCSprite setString:]: unrecognized selector sent to instance 0x897cbd0'
One possibility is that somewhere in your code, numberStat[1] is being over-released, and by the time you come to assign a string to it, a CCSprite has moved into the memory that it occupied.
I'm getting this crash, but, in my code I am using a string. I've been working on this one piece of code for 2 hours now and I just can't see what I'm missing! Any ideas?
NSString *codeR = [NSString stringWithFormat:#"%#", [[object objectForKey:#"code"] stringValue]];
if([codeR isEqualToString:#"200"])
Error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0x181cf0'
I would be very grateful input, this is confusing the hell out of me!
Thanks.
Get rid of silly redundancy, see what happens.
NSString *codeR = [[object objectForKey:#"code"] stringValue];
// mysterious missing code
if ([coreR isEqualToString:#"200"]) // etc
Also, are you sure the error is raised from the if statement you posted? It could be coming from elsewhere.
NSString *codeR = [[object objectForKey:#"code"] stringValue];
if ([codeR isEqualToString:#"200"])
{
// Do stuff...
}