checking NSArray values - objective-c

I have an NSArray (RSIatAddr), and I want to check whether the object at the given index = 0 (or some other arbitrary constant) but the following code gives me no warnings / error ; but is throwing an exception
if ([[RSIatAddr objectAtIndex:j] isEqualToNumber:nil]) {
[sumRSI addObject:[NSNumber numberWithInt:[[RSIatAddr objectAtIndex:j]intValue]*
[[sumRSI objectAtIndex:j] intValue]]]; }
The error I'm getting:
2012-10-02 00:42:00.266 NetSearch+DetectLocation[3741:707]
*** Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSCFNumber compare:]: nil argument'

isEqualToNumber: takes an NSNumber as an argument, not the integer that you're passing.
The integer that you're using, 0, happens to be the value of nil, but any integer would be extremely unlikely to be a valid pointer value for an NSNumber, and would also therefore crash.

Without seeing the code that actually fills your array, its likely the array is holding a different type than you are expecting. Try setting a breakpoint right before that line of code, and typing "po [[RSIatAddr objectAtIndex:j] class]" and see what is actually there, then you can also try your isEqualToNumber in the debug window to see if that succeeds.
I just implemented this in the AppDelegate of a new iOS App and it works:
NSArray *array = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:0], [NSNumber numberWithInt:1], nil];
NSLog(#"%#", array);
for (NSNumber *num in array) {
if ([num isEqualToNumber:[NSNumber numberWithInt:0]]) {
NSLog(#"Equal");
} else {
NSLog(#"Not Equal");
}
}

Related

"unrecognized selector sent to instance" for NSArrayI

I have the following code which gives the "unrecognized selector sent to instance" error for the NSArray. I've not been able to figure this out and feel its something simple I'm missing here. I can post more if needed.
Quote *myQuote;
NSArray *myQuotes = theSubject.quotes;
//START LOOP HERE
for (myQuote in myQuotes){
NSLog(#" excerpt = %#", myQuote.excerpt);
NSLog(#" desc2 = %#", myQuote.desc2);
NSLog(#" quote_date = %#", myQuote.quote_date);
NSLog(#" myQuote = %#", myQuote);
I believe the problem is in this function which returns an array of Quotes:
- (NSArray *) getQuotesFromSubId:(NSInteger )subId {
QuotesAppDelegate *appDelegate = (QuotesAppDelegate *)[[UIApplication sharedApplication] delegate];
self.quoteMaps = [appDelegate quoteMaps];
self.quotes = [appDelegate quotes];
//get the quote_ids from quote_map for this subject_id
NSString *stringOfSubjectId = [NSString stringWithFormat:#"%ld", (long)subId];
NSPredicate *filterSubjectId = [NSPredicate predicateWithFormat:#"subject_id == %#", stringOfSubjectId];
NSArray *quoteMapSection = [self.quoteMaps filteredArrayUsingPredicate:filterSubjectId];
NSMutableArray *quoteSection = [[NSMutableArray alloc] init];
NSArray *quoteToAdd = [[NSArray alloc] init];
for (QuoteMap *qm in quoteMapSection){
//get the quote_ids from quote_map for this subject_id
NSPredicate *filter = [NSPredicate predicateWithFormat:#"quote_id == %#", qm.quote_id];
quoteToAdd = [self.quotes filteredArrayUsingPredicate:filter];
[quoteSection addObject:quoteToAdd];
}
return quoteSection;
}
This is where I call it:
QuotesAppDelegate *appDelegate = (QuotesAppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *myQuotes = [appDelegate getQuotesFromSubId:selectedSubject.subject_id];
NSMutableArray *mArray = [appDelegate createMutableArray:myQuotes];
selectedSubject.quotes = mArray;
NSMutableArray *mutableArray = [appDelegate createMutableArray:myQuotes];
selectedSubject.quotes = mutableArray;
I got the following error
2016-02-23 00:24:20.383 Quotes[10631:3698114] -[__NSArrayI excerpt]: unrecognized selector sent to instance 0x15ebbeff0
2016-02-23 00:24:29.164 Quotes[10631:3698114] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI excerpt]: unrecognized selector sent to instance 0x15ebbeff0'
*** First throw call stack:
(0x182b55900 0x1821c3f80 0x182b5c61c 0x182b595b8 0x182a5d68c 0x100078b2c 0x1000642d0 0x187cb17f4 0x187cb1f8c 0x187b9fc90 0x187ba2e88 0x187977284 0x187883394 0x187882e90 0x187882d18 0x185259c00 0x10011dbb0 0x100123658 0x182b0cbb0 0x182b0aa18 0x182a39680 0x183f48088 0x1878b0d90 0x100040398 0x1825da8b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
You are sending -excerpt to the members (myQuote) of myQuotes. The runtime says that NSArray (NSArrayI is an internal subclass) instances cannot understand -excerpt.
So the type of the member is NSArray. We cannot know, why you have instances of NSArray in the array MyQuotes, because we do not see that code. Likely that happened when you tried to add new quotes to the quotes property and incidentally added the whole array instead of its members.
To your edit:
This is wrong:
NSArray *quoteToAdd = [[NSArray alloc] init]; // This is an array. It identifier should be quote*s*ToAdd
// BTW: This above code is meaningless, because you do not need to create an array instance. Simply omit "[[NSArray alloc] init]". But this is not your problem.
for (QuoteMap *qm in quoteMapSection){
…
quoteToAdd = [self.quotes filteredArrayUsingPredicate:filter]; // filtered array returns an *array*
[quoteSection addObject:quoteToAdd]; // You add the *array* instead of the member of the array.
}
What you get back is an array. Then you add the array itself (not its members) to the existing array. As result you get an array that contains an array.
Simply change …
[quoteSection addObject:quoteToAdd];
… to:
[quoteSection addObjectsFromArray:quoteToAdd];
(And change the reference name to a plural form for better readability.)

Trouble Adding Object To NSMutableArray in For Loop

I'm having some trouble adding an object to an NSMutableArray in a for loop. When I try it, I get an error:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'
Blockquote
I've looked at other questions very similar to this and they are solved because the array was immutable or they were reading off NSUserDefaults, however I am doing neither of those things.
I download some JSON and parse it using NSJSONSelialization, and the idea is that I have an almost twitter-like stream of activity coming down from the top of the UITableView. Here's my code:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
if (isDownloadingFirstTime){
isDownloadingFirstTime = NO;
dataArray = [Methods parseJSONDataWithData:data];
[mainTableView reloadData];
} else{
[refreshControl endRefreshing];
NSArray *tempArray = [Methods parseJSONDataWithData:data];
for (int num = 0; num < tempArray.count; num++){
[dataArray addObject:[tempArray objectAtIndex:num]];
NSArray *indexPathArray = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]];
[mainTableView beginUpdates];
[mainTableView insertRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationTop];
[mainTableView endUpdates];
}
}
data = [NSMutableData data];
}
I get the exception on the first line of the for loop, when I try to addObject:
I in no way am using NSUserDefaults in this class and I'm 100% sure that dataArray is an NSMutableArray.
Any help or advice is appreciated!
Your dataArray isn't a mutable array. You might did type the pointer as one, but that doesn't make the object itself mutable. The easiest would by to wit a mutable copy tho dataArray.
dataArray = [[Methods parseJSONDataWithData:data] mutableCopy];

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: NSArrayM objectForKey

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM objectForKey:]: unrecognized selector sent to instance 0x12e654c0.
I am loading data on tableview from Array that has two dictionary objects. Dictionary object contains 2 nsstring object when ViewDidLoad called the code is below
while (sqlite3_step(statement) == SQLITE_ROW) {
NSString* delID = [NSString stringWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
NSString* name =[NSString stringWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
NSMutableDictionary *dict=[NSMutableDictionary dictionary];
[dict setObject:delID forKey:#"delID"];
[dict setObject:name forKey:#"name"];
[self.arr addObject:dict];
It never crash for first row but on second row indexPath.row==1 it always crash please see the screen shot below. Thanks for help
Here is I am filling self.arr again
-(void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
if ([datePicker1.CurrentDate length]) {
UIButton *btn=(UIButton*)[self.view viewWithTag:btnTag];
[btn setTitle:datePicker1.CurrentDate forState:UIControlStateNormal];
}
if ([self.searchDel.arrSelectDelAdd count ])
{
[self.arr addObject:self.searchDel.arrSelectDelAdd];
[self.tblDelivery reloadData];
}
}
Remove the if condition from your code. As it is just adding first dictionary into the array not the second one.
//if (i==0){
[self.arr addObject:dict];
//}
Try this :)
Sorry to bother all of you Actually the problem is that I am adding second or another object like
[self.arr addObject:self.searchDel.arrSelectDelAdd]; //Incorrect, that is adding NSArray type not dictionary
then getting values in cellForRowAtIndexPath
NSDictionary *dict=[arr objectAtIndex:indexPath.row];//here dict will contain NSSArray type not dict type object its causing to crash app.
cell.lblID.text=(NSString*)[dict objectForKey:#"delID"];// at this line.
cell.lblName.text=(NSString*)[dict objectForKey:#"name"];
[self.arr addObjectsFromArray:self.searchDel.arrSelectDelAdd]; // correct, thats the solution giving contents of NSSArray and now working my code

"for in" objective c empty array

I came to notice that executing a for/in operation in objective c on an initialized empty NSMutableArray was not working as expected.
Simplified code is :
+(void) convertArray: (NSMutableArray*)arrayIN {
NSMutableArray *arrayOUT = [NSMutableArray array];
NSLog(#"is nil %d - count %d", !arrayIN, [arrayIN count]);
for(NSObject *o in arrayIN)
[arrayOUT addObject:[o convertToAnotherClass]];
}
Actual code is :
+(BOOL) writeTasks: (NSArray*)tasksArray {
NSMutableArray *arr = [NSMutableArray array];
NSLog(#"is nil %d - count %d", !arr, [arr count]);
for(Task *t in tasksArray)
[arr addObject:[t getDictionary]];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:arr options:NSJSONWritingPrettyPrinted error:&error];
if (! jsonData) {
NSLog(#"Got an error: %#", error);
return NO;
} else {
//NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
[jsonData writeToFile:path options:NSDataWritingAtomic error:nil];
return YES;
}
}
the suprising thing is that executing [dummyClass convertArray:[NSMutableArray array]] is showing this :
2012-06-25 13:51:34.236 Planorama[740:707] is nil 0 - count 0
2012-06-25 13:51:34.239 Planorama[740:707] -[__NSArrayM convertToAnotherClass]: unrecognized selector sent to instance 0xde9b580
(lldb)
Why ? arrayIN is empty, why is convertToAnotherClass even called ?
if you use the block based enumeration it will work the way you want.
Also, the output indicates that o is set to some instance of something, so you may have another problem.
Elegant way to get all objects of a specific type in an Objective-C array
Lastly, it looks like this is a static method, but your example calls it as an instance method.
As Joshua Smith pointed out : I am not checking the count of the iterated array. The iterated array was not empty and contained itself because if a mistyped line :
[tasks addObject:tasks]
instead of
[tasks addObject:task]
in a previous method..
Thanks everyone !
PS : the link of Joshua Smith is very useful ! Future readers : check it out !

Testing for null in objective-c

I have the following code in a loop
NSArray * images = [definitionDict objectForKey:#"Images"];
NSLog(#"images in definitionDict %#", images);
if (!images )
NSLog(#"NULL");
else
NSLog(#"NOTNULL");
which gives the following outputs
images in definitionDict (
"/some/brol/brol.jpg"
)
NOTNULL
images in definitionDict <null>
NOTNULL
I do not understand the second case, where the images array is null. Why is this not detected correctly in my test ? How can I debug such a problem ?
<null> is not nil. nil will print (null) when printed. What you have is an NSNull. NSNull IS an object, it just doesn't respond to much. Its available as a placeholder for you to use.
To test for NSNull you can use if ([images isEqual:[NSNull null]])
See the docs for more info on NSNull
If you want to print out the memory address of an Objective-C object, or any other pointer, you should use the flag %p not %#. The flag %#, expects a string.
However if the argument isn't a string, NSLog will automatically call -description on the passed object. And when the method returns an NSNullobject, the -descriptionon that object returns the string <null>
NSObject *o = nil;
NSLog(#"%p", o);
Output: 0x00000000
NSObject *o = [[NSObject alloc] init];
NSLog(#"%p", o);
[o release];
Output: something like 0x12345678
Mind:
NSNull *n = [NSNull null];
NSLog(#"%p", n);
Output: a memory address that always will be the same, but will differ from 0x00000000
The correct way to test if their are objects in the array is like this.
NSArray *myArray = [someObject array];
if([myArray isEqual:[NSNull null]]) {
NSLog(#"No objects");
} else {
NSLog(#"%d objects.", (int)[myArray length];
}