So i'm searching my Core Data for an item that is inside the current map's longitude and latitude. Everytime i run the statement it crashes.
the code:
NSError *error = nil;
NSFetchRequest *boutiqueRequest = [[NSFetchRequest alloc] init];
NSPredicate *predicateToRun = nil;
[boutiqueRequest setEntity:[NSEntityDescription entityForName:#"Boutique" inManagedObjectContext:managedObjectContext]];
NSLog(#"NE Longitude: %f", [neCoordLong floatValue]);
NSLog(#"NE Latitude: %f", [neCoordLat floatValue]);
NSLog(#"SW Longitude: %f", [swCoordLong floatValue]);
NSLog(#"SW Latitude: %f", [swCoordLat floatValue]);
NSPredicate *longPredicate = [NSPredicate predicateWithFormat: #"longitude BETWEEN %#", [NSArray arrayWithObjects:neCoordLong, swCoordLong, nil]];
NSPredicate *latPredicate = [NSPredicate predicateWithFormat: #"latitude BETWEEN %#", [NSArray arrayWithObjects:neCoordLat, swCoordLat, nil]];
predicateToRun = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:longPredicate, latPredicate, nil]];
[boutiqueRequest setPredicate:predicateToRun];
NSLog(#"%#", [boutiqueRequest predicate]);
NSArray *results = [managedObjectContext executeFetchRequest:boutiqueRequest error:&error];
As soon as I call the executeFetchRequest it gives me the following crash report
2011-02-24 17:42:43.183 DL2[363:207] NE Longitude: 153.5058
2011-02-24 17:42:43.183 DL2[363:207] NE Latitude: -27.811142
2011-02-24 17:42:43.183 DL2[363:207] SW Longitude: 153.286057
2011-02-24 17:42:43.184 DL2[363:207] SW Latitude: -28.033804
2011-02-24 17:42:43.184 DL2[363:207] longitude BETWEEN {153.5058, 153.2861} AND latitude BETWEEN {-27.81114, -28.0338}
2011-02-24 13:57:18.916 DL2[9628:207] -[NSCFNumber constantValue]: unrecognized selector sent to instance 0x954ba80
2011-02-24 13:57:18.925 DL2[9628:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFNumber constantValue]: unrecognized selector sent to instance 0x954ba80'
*** Call stack at first throw:
(
0 CoreFoundation 0x0121abe9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0136f5c2 objc_exception_throw + 47
2 CoreFoundation 0x0121c6fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x0118c366 ___forwarding___ + 966
4 CoreFoundation 0x0118bf22 _CF_forwarding_prep_0 + 50
5 CoreData 0x00e18a0b -[NSSQLSimpleWhereIntermediate _generateSQLBetweenStringInContext:] + 1211
6 CoreData 0x00d48931 -[NSSQLSimpleWhereIntermediate generateSQLStringInContext:] + 897
7 CoreData 0x00d4843d -[NSSQLCompoundWhereIntermediate _generateMulticlauseStringInContext:] + 205
8 CoreData 0x00d48342 -[NSSQLCompoundWhereIntermediate generateSQLStringInContext:] + 770
9 CoreData 0x00d47afa -[NSSQLFetchIntermediate generateSQLStringInContext:] + 122
10 CoreData 0x00e0b31d -[NSSQLGenerator newSQLStatementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:] + 413
11 CoreData 0x00d43a78 -[NSSQLAdapter _newSelectStatementWithFetchRequest:ignoreInheritance:] + 488
12 CoreData 0x00d43881 -[NSSQLAdapter newSelectStatementWithFetchRequest:] + 49
13 CoreData 0x00d4372e -[NSSQLCore newRowsForFetchPlan:] + 430
14 CoreData 0x00d42ab5 -[NSSQLCore objectsForFetchRequest:inContext:] + 357
15 CoreData 0x00d4266e -[NSSQLCore executeRequest:withContext:error:] + 206
16 CoreData 0x00df20ec -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 1084
17 CoreData 0x00d3f807 -[NSManagedObjectContext executeFetchRequest:error:] + 359
18 DL2 0x00021060 -[BoutiqueListViewController getBoutiquesToShow] + 1449
19 DL2 0x0002164f -[BoutiqueListViewController viewDidLoad] + 211
20 UIKit 0x003f265e -[UIViewController view] + 179
21 DL2 0x0001ff4e -[BoutiqueMapTabViewController openList] + 698
22 DL2 0x0001f9f3 -[BoutiqueMapTabViewController tabBar:didSelectItem:] + 110
23 UIKit 0x00542167 -[UITabBar _sendAction:withEvent:] + 283
24 UIKit 0x00344a6e -[UIApplication sendAction:to:from:forEvent:] + 119
25 UIKit 0x003d31b5 -[UIControl sendAction:to:forEvent:] + 67
26 UIKit 0x003d5647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
27 UIKit 0x003d316c -[UIControl sendActionsForControlEvents:] + 49
28 UIKit 0x00344a6e -[UIApplication sendAction:to:from:forEvent:] + 119
29 UIKit 0x003d31b5 -[UIControl sendAction:to:forEvent:] + 67
30 UIKit 0x003d5647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
31 UIKit 0x003d41f4 -[UIControl touchesEnded:withEvent:] + 458
32 UIKit 0x003690d1 -[UIWindow _sendTouchesForEvent:] + 567
33 UIKit 0x0034a37a -[UIApplication sendEvent:] + 447
34 UIKit 0x0034f732 _UIApplicationHandleEvent + 7576
35 GraphicsServices 0x01b3da36 PurpleEventCallback + 1550
36 CoreFoundation 0x011fc064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
37 CoreFoundation 0x0115c6f7 __CFRunLoopDoSource1 + 215
38 CoreFoundation 0x01159983 __CFRunLoopRun + 979
39 CoreFoundation 0x01159240 CFRunLoopRunSpecific + 208
40 CoreFoundation 0x01159161 CFRunLoopRunInMode + 97
41 GraphicsServices 0x01b3c268 GSEventRunModal + 217
42 GraphicsServices 0x01b3c32d GSEventRun + 115
43 UIKit 0x0035342e UIApplicationMain + 1160
44 DL2 0x000028fc main + 102
45 DL2 0x0000288d start + 53
I just can't seem to see the problem. I don't know if i'm too close to it, or if it's something to do with it being a Float or what! Any help would be greatly appreciated
Well i wasn't able to solve why the Between function didn't work - but mysql doesn't allow BETWEEN on floating point numbers either. So i'm going to assume that it's a similar reason.
I changed my code to merely create it's own between statement.
NSPredicate *longPredicate = nil;
NSPredicate *latPredicate = nil;
if ([neCoordLong floatValue] > [swCoordLong floatValue])
{
longPredicate = [NSPredicate predicateWithFormat: #" longitude <= %# AND longitude >= %#", neCoordLong, swCoordLong];
}else {
longPredicate = [NSPredicate predicateWithFormat: #" longitude <= %# AND longitude >= %#", swCoordLong, neCoordLong];
}
if ([neCoordLat floatValue] > [swCoordLat floatValue])
{
latPredicate = [NSPredicate predicateWithFormat: #" latitude <= %# AND latitude >= %#", neCoordLat, swCoordLat];
}else {
latPredicate = [NSPredicate predicateWithFormat: #" latitude <= %# AND latitude >= %#", swCoordLat, neCoordLat];
}
Hopefully this helps someone else
I had a similar error as well. I am pretty sure it is a very low level database related issue. Here is some more information I have -
a. With a inmemory database, I could run a test case with exactly the same data just fine.
b. When I got the error "-[__NSCFNumber constantValue]: unrecognized selector sent to instance 0xa9e4ca0". I did
(lldb) po 0xa9e4ca0
$0 = 178146464 -96.24999189101783
Not sure where 178146464 coming from. I will try the manual "between" now.
I don't see the exact cause either, and you haven't shown the code where the rest of boutiqueRequest's properties are set and the fetch fired (not that it matters unless you set the predicate again or something else funky), but the report
2011-02-24 13:57:18.916 DL2[9628:207] -[NSCFNumber constantValue]: unrecognized selector sent to instance 0x954ba80
indicates you're sending the message -constantValue to an object of class NSCFNumber (a toll-free NSNumber/CFNumber instance), which doesn't handle it. So I suggest you try using only portions of the predicate to find which doesn't and does cause some expression within the predicate to be substituted with an NSCFNumber instance.
At the beginning of your fetch you're declaring
NSPredicate *predicateToRun = nil;
And then you assign it a NSCompoundPredicate to it in
predicateToRun = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:longPredicate, latPredicate, nil]];
See if that solves it.
Rog
Related
My stacktrace is related to maps..
NSGenericException occurs, if we try modify the array, which is being enumerated... I have taken-care about not modifying the enumerating Array.
for (int k=0;k<[[af factsArray] count];k++)
//here af is my object
{
Facts *f = [[af factsArray] objectAtIndex:k];
//here i'm removing unecessary characters from my point String
NSCharacterSet *doNotWant = [NSCharacterSet characterSetWithCharactersInString:#"POINT()"];
NSString *pointsStr = [[[f.factPosition mutableCopy] componentsSeparatedByCharactersInSet:doNotWant] componentsJoinedByString:#""];
NSArray *pieces = [[pointsStr componentsSeparatedByString:#" "] copy];
CGPoint point = CGPointMake([[pieces objectAtIndex:2] floatValue], [[pieces objectAtIndex:1] floatValue]);
NSValue *val = [NSValue valueWithCGPoint:point];
[routePointsArray addObject:val];
}
NSInteger pointsCount = routePointsArray.count;
CLLocationCoordinate2D pointsToUse[pointsCount];
for(int i = 0; i < pointsCount; i++)
{
CGPoint p = [[routePointsArray objectAtIndex:i] CGPointValue];
pointsToUse[i] = CLLocationCoordinate2DMake(p.x,p.y);
}
MKPolyline *myPolyline = [MKPolyline polylineWithCoordinates:pointsToUse count:pointsCount];
[routeOverlays addObject:myPolyline];
NSLog(#"routeOverlays count:%d",[routeOverlays count]);
//adding overlays
dispatch_async(dispatch_get_main_queue(), ^{
[self.map addOverlays:routeOverlays];
});
Can anybody tell me the problem with the code because it crashes sometimes and sometimes doesn't.
here is my stacktrace
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x12a9f7d0> was mutated while being enumerated.'
*** First throw call stack:
(
0 CoreFoundation 0x01a2f5e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x017b28b6 objc_exception_throw + 44
2 CoreFoundation 0x01abf3b5 __NSFastEnumerationMutationHandler + 165
3 VectorKit 0x04029d7e -[VKMapModel layoutScene:withContext:] + 3854
4 VectorKit 0x0401fc8e -[VKModelObject layoutSceneIfNeeded:withContext:] + 110
5 VectorKit 0x04028bff -[VKMapModel layoutSceneIfNeeded:withContext:] + 143
6 VectorKit 0x0401fd35 -[VKModelObject layoutSceneIfNeeded:withContext:] + 277
7 VectorKit 0x0403f278 -[VKWorld layoutScene:withContext:] + 56
8 VectorKit 0x0402eac6 -[VKScreenCanvas drawWithTimestamp:] + 358
9 VectorKit 0x04019c15 -[VKMapCanvas drawWithTimestamp:] + 149
10 VectorKit 0x0402e4ee -[VKScreenCanvas onTimerFired:] + 142
11 libobjc.A.dylib 0x017c481f -[NSObject performSelector:withObject:] + 70
12 VectorKit 0x041adbdc -[VGLDisplayLink _displayLinkFired:] + 60
13 QuartzCore 0x045f3fca _ZN2CA7Display15DisplayLinkItem8dispatchEv + 48
14 QuartzCore 0x045f3e86 _ZN2CA7Display11DisplayLink14dispatch_itemsEyyy + 310
15 QuartzCore 0x045f43ab _ZN2CA7Display16TimerDisplayLink8callbackEP16__CFRunLoopTimerPv + 123
16 CoreFoundation 0x019edc46 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
17 CoreFoundation 0x019ed62d __CFRunLoopDoTimer + 1181
18 CoreFoundation 0x019d5698 __CFRunLoopRun + 1816
19 CoreFoundation 0x019d4b33 CFRunLoopRunSpecific + 467
20 CoreFoundation 0x019d494b CFRunLoopRunInMode + 123
21 GraphicsServices 0x02c469d7 GSEventRunModal + 192
22 GraphicsServices 0x02c467fe GSEventRun + 104
23 UIKit 0x0031894b UIApplicationMain + 1225
24 SnapTraq 0x0002029d main + 141
25 libdyld.dylib 0x022c1725 start + 0
)
libc++abi.dylib: terminating with uncaught exception of type NSException
I would like to thank #micantox for his attempt to solve my problem...
Anyways, I have solved my own problem.
I was trying to execute the loop from different threads.. that caused the actual problem.
one thread is add the annotations using the NSArray and other thread is removing those NSArray objects. to avoid this problem i have used
#synchronized(self)
{
// your code goes here
}
I am a starter in iPhone. I wanted to do case-insensitive search. Database helper used: Core Data.
Following is my code:
-(WebAttendee *) FindAttendeeBy:(NSString *) badgeID_
{
AppDelegate_Shared *delegate1 = [[UIApplication sharedApplication]delegate];
badgeID_=[badgeID_ stringByReplacingOccurrencesOfString:#"\\" withString:#"\\\\"];
badgeID_=[badgeID_ stringByReplacingOccurrencesOfString:#"'" withString:#"\\'"];
self.managedObjectContext = delegate1.managedObjectContext;
return (WebAttendee *)[self FetchManagedObject:#"WebAttendee" :[NSString stringWithFormat:# "Barcode LIKE [c] %#",badgeID_ ]];
}
-(NSManagedObject *)FetchManagedObject:(NSString *)entity_:(NSString *)predicate_
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entity_ inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicate_];
[request setPredicate:predicate];
NSError *error = nil;
//--------------------------crashes at this step---------------------------------
mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
NSLog(#"FetchResult=%#",mutableFetchResults);
[request release];
if (mutableFetchResults == nil) {
// Handle the error.
}
if([mutableFetchResults count]!=0)
return [mutableFetchResults objectAtIndex:0];
else {
return nil;
}
}
but i am getting the following error:
2012-07-05 12:58:52.917 SpotLighter[963:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unimplemented SQL generation for predicate (Barcode LIKE[c] 1123)'
*** Call stack at first throw:
(
0 CoreFoundation 0x01783be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x018d85c2 objc_exception_throw + 47
2 CoreData 0x00fe4676 -[NSSQLGenerator newSQLStatementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:] + 1270
3 CoreData 0x00f1ca78 -[NSSQLAdapter _newSelectStatementWithFetchRequest:ignoreInheritance:] + 488
4 CoreData 0x00f1c881 -[NSSQLAdapter newSelectStatementWithFetchRequest:] + 49
5 CoreData 0x00f1c72e -[NSSQLCore newRowsForFetchPlan:] + 430
6 CoreData 0x00f1bab5 -[NSSQLCore objectsForFetchRequest:inContext:] + 357
7 CoreData 0x00f1b66e -[NSSQLCore executeRequest:withContext:error:] + 206
8 CoreData 0x00fcb0ec -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 1084
9 CoreData 0x00f18807 -[NSManagedObjectContext executeFetchRequest:error:] + 359
10 SpotLighter 0x0000ff26 -[EntityCommands FetchManagedObject::] + 310
11 SpotLighter 0x0001436e -[WebAttendeeController FindAttendeeBy:] + 300
12 SpotLighter 0x0009aac6 -[MapBadge Map:::] + 4673
13 SpotLighter 0x000687d7 -[SpotLighterHomeScreen SpotLighterDataReceived::::] + 1111
14 SpotLighter 0x0002ca83 -[SpotlighterViewController txtNumericBadgeFieldDone:] + 445
15 UIKit 0x0051da6e -[UIApplication sendAction:to:from:forEvent:] + 119
16 UIKit 0x005ac1b5 -[UIControl sendAction:to:forEvent:] + 67
17 UIKit 0x005ae647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
18 UIKit 0x005ad1f4 -[UIControl touchesEnded:withEvent:] + 458
19 UIKit 0x007a8987 _UIGestureRecognizerSortAndSendDelayedTouches + 3609
20 UIKit 0x007a90fc _UIGestureRecognizerUpdateObserver + 927
21 CoreFoundation 0x01764fbb __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
22 CoreFoundation 0x016fa0e7 __CFRunLoopDoObservers + 295
23 CoreFoundation 0x016c2bd7 __CFRunLoopRun + 1575
24 CoreFoundation 0x016c2240 CFRunLoopRunSpecific + 208
25 CoreFoundation 0x016c2161 CFRunLoopRunInMode + 97
26 GraphicsServices 0x01f07268 GSEventRunModal + 217
27 GraphicsServices 0x01f0732d GSEventRun + 115
28 UIKit 0x0052c42e UIApplicationMain + 1160
29 SpotLighter 0x00002168 main + 102
30 SpotLighter 0x000020f9 start + 53
)
terminate called after throwing an instance of 'NSException'
return (WebAttendee *)[self FetchManagedObject:#"WebAttendee" :[NSString stringWithFormat:# "Barcode LIKE [c] %#",badgeID_ ]];
was giving error...
I replaced the above line with
return (WebAttendee *)[self FetchManagedObject:#"WebAttendee" :[NSString stringWithFormat:# "Barcode LIKE [c] '%#'",badgeID_ ]];
and it worked fine!
I have a highscore.plist file with type NSDictionary of 5 items each containing NSNumber - score and String - Name ,
I want to sort scores in descending order . This is what i am trying to do :
NSString *location = [[NSBundle mainBundle] pathForResource:#"HighScores" ofType:#"plist"];
NSArray *highscoredata = [[NSArray alloc] initWithContentsOfFile:location];
self.sortedhighscores = [highscoredata sortedArrayUsingFunction:intSort context:0];
//intSort function :
NSInteger intSort(id num1, id num2, void *context) {
int v1 = [num1 intValue];
int v2 = [num2 intValue];
if (v1 < v2)
return NSOrderedAscending;
else if (v1 > v2)
return NSOrderedDescending;
else
return NSOrderedSame;
}
This is the error i receive :
2011-11-18 12:36:25.574 Test[27723:207] -[__NSCFDictionary intValue]: unrecognized selector sent to instance 0x4b66d50
2011-11-18 12:36:25.576 Test[27723:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary intValue]: unrecognized selector sent to instance 0x4b66d50'
*** Call stack at first throw:
(
0 CoreFoundation 0x00f355a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x01089313 objc_exception_throw + 44
2 CoreFoundation 0x00f370bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x00ea6966 ___forwarding___ + 966
4 CoreFoundation 0x00ea6522 _CF_forwarding_prep_0 + 50
5 Test 0x000035e8 intSort + 36
6 CoreFoundation 0x00e9c3cf __CFSimpleMergeSort + 591
7 CoreFoundation 0x00e9c1c6 __CFSimpleMergeSort + 70
8 CoreFoundation 0x00e9c06c CFSortIndexes + 268
9 CoreFoundation 0x00ebf42c -[NSArray sortedArrayWithOptions:usingComparator:] + 380
10 CoreFoundation 0x00ebf21a -[NSArray sortedArrayUsingFunction:context:] + 106
11 Test 0x000036f7 -[HighScore_ViewController viewDidLoad] + 192
12 UIKit 0x00372089 -[UIViewController view] + 179
13 UIKit 0x00373a3d -[UIViewController viewControllerForRotation] + 63
14 UIKit 0x0036f988 -[UIViewController _visibleView] + 90
15 UIKit 0x0061193c -[UIClientRotationContext initWithClient:toOrientation:duration:andWindow:] + 354
16 UIKit 0x002e981e -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 954
17 UIKit 0x00571619 -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 1381
18 UIKit 0x0037665d -[UIViewController presentModalViewController:withTransition:] + 3478
19 Test 0x0000296b -[Test_ViewController ShowLeaderboardsModal:] + 198
20 UIKit 0x002c24fd -[UIApplication sendAction:to:from:forEvent:] + 119
21 UIKit 0x00352799 -[UIControl sendAction:to:forEvent:] + 67
22 UIKit 0x00354c2b -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
23 UIKit 0x003537d8 -[UIControl touchesEnded:withEvent:] + 458
24 UIKit 0x002e6ded -[UIWindow _sendTouchesForEvent:] + 567
25 UIKit 0x002c7c37 -[UIApplication sendEvent:] + 447
26 UIKit 0x002ccf2e _UIApplicationHandleEvent + 7576
27 GraphicsServices 0x0188d992 PurpleEventCallback + 1550
28 CoreFoundation 0x00f16944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
29 CoreFoundation 0x00e76cf7 __CFRunLoopDoSource1 + 215
30 CoreFoundation 0x00e73f83 __CFRunLoopRun + 979
31 CoreFoundation 0x00e73840 CFRunLoopRunSpecific + 208
32 CoreFoundation 0x00e73761 CFRunLoopRunInMode + 97
33 GraphicsServices 0x0188c1c4 GSEventRunModal + 217
34 GraphicsServices 0x0188c289 GSEventRun + 115
35 UIKit 0x002d0c93 UIApplicationMain + 1160
36 Test 0x00001f3c main + 102
37 Test 0x00001ecd start + 53
)
terminate called after throwing an instance of 'NSException'
But when I try to run it on Simulator (iOS) it crashes, Im new to Objective C , I think im not doing it right when comparing NSNumber(scores) in array . Any help would be appreciated . Thanks!
Per your description, highscoredata is an array of NSDictionarys. So the result of your call to sortedArrayUsingFunction:context is that intSort is called to compare dictionaries. As per the error reported on the console, NSDictionary does not implement intValue.
To adjust your code directly, try:
NSInteger intSort(id num1, id num2, void *context) {
// assuming the numerical score is in the dictionary
// under the key 'score'
int v1 = [[num1 objectForKey:#"score"] intValue];
int v2 = [[num2 objectForKey:#"score"] intValue];
...
So that compares two dictionaries by retrieving from each the NSNumber representing the score, and comparing that.
NSNumber actually implements compare: for itself, so a more compact version would be:
NSInteger intSort(id num1, id num2, void *context) {
NSNumber *v1 = [num1 objectForKey:#"score"];
NSNumber *v2 = [num2 objectForKey:#"score"];
return [v1 compare:v2];
}
Building on that, because of the way key paths work in Objective-C, an even shorter version would be:
NSArray *highscoredata = [[NSArray alloc] initWithContentsOfFile:location];
NSSortDescriptor *sortDescriptor =
[NSSortDescriptor sortDescriptorWithKey:#"score" ascending:YES];
self.sortedhighscores = [highscoredata
sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
No need for an intSort function at all — NSDictionary knows how to look something up with the key "score" and the things that it looks up are NSNumbers, which know how to compare themselves.
Sort your highscore data in descending order use this code
NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:nil ascending:NO selector:#selector(localizedCompare:)];
NSArray* sortedArray = [highScoreArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
Here we use localizedCompare: to compare the strings, and pass NO to the ascending: option to sort in descending order.
It seems that id num1 and id num2 that you are passing to function intSort are not NSNumber. They seems to be NSDictionary object.
This is a different situation than this question, as the solution provided doesn't work and the stack is different.
Periodical crash when I save data using coredata.
The stack trace isn't 100% clear on where this is happening, but I'm certain it's this routine that's being called. It's either the save: in this method or the one following.
Code:
-(void)saveWine {
if ([self validInfo]) {
Wine *wine = (Wine *)wineToEdit;
if (wine == nil) {
wine = (Wine *)[NSEntityDescription insertNewObjectForEntityForName:#"Wine" inManagedObjectContext:self.managedObjectContext];
}
wine.uuid = [Utils createUUID];
wine.name = self.wineNameField.text;
wine.vineyard = self.vineyardField.text;
wine.vintage = [[self numberFormatter] numberFromString:self.vintageField.text];
wine.timeStamp = [NSDate date];
wine.rating = [NSNumber numberWithInt:self.ratingControl.selectedSegmentIndex];
wine.partnerRating = [NSNumber numberWithInt:self.partnerRatingControl.selectedSegmentIndex];
wine.varietal = self.currentVarietal;
wine.tastingNotes = self.currentTastingNotes;
wine.dateTasted = self.currentDateTasted;
wine.tastingLocation = [[ReferenceDataAccessor defaultReferenceDataAccessor] addEntityForType:TASTING_LOCATION
withName:self.currentWhereTasted];
id type = [[ReferenceDataAccessor defaultReferenceDataAccessor] entityForType:WINE_TYPE
withOrdinal:self.typeControl.selectedSegmentIndex];
wine.type = type;
NSError *error;
NSLog(#"Saving %#",wine);
if (![self.managedObjectContext save:&error]) {
[Utils showAlertMessage:#"There was a problem saving your wine; try restarting the app" withTitle:#"Problem saving"];
NSLog(#"Error while saving new wine %#, %#", error, [error userInfo]);
}
}
else {
NSLog(#"ERROR - someone is calling saveWine with invalid info!!");
}
}
Code for addEntityForType:withName::
-(id)addEntityForType:(NSString *)type withName:(NSString *)name {
if ([Utils isStringBlank:name]) {
return nil;
}
id existing = [[ReferenceDataAccessor defaultReferenceDataAccessor] entityForType:type withName:name];
if (existing != nil) {
NSLog(#"%# with name %# already exists",type,name);
return existing;
}
NSManagedObject *newEntity = [NSEntityDescription insertNewObjectForEntityForName:type
inManagedObjectContext:self.managedObjectContext];
[newEntity setValue:name forKey:#"name"];
NSError *error;
if (![self.managedObjectContext save:&error]) {
[Utils showAlertMessage:[NSString stringWithFormat:#"There was a problem saving a %#",type] withTitle:#"Database Probem"];
[Utils logErrorFully:error forOperation:[NSString stringWithFormat:#"saving new %#",type ]];
}
return newEntity;
}
Stack trace:
Thread 0 Crashed:
0 libSystem.B.dylib 0x311de2d4 __kill + 8
1 libSystem.B.dylib 0x311de2c4 kill + 4
2 libSystem.B.dylib 0x311de2b6 raise + 10
3 libSystem.B.dylib 0x311f2d72 abort + 50
4 libstdc++.6.dylib 0x301dea20 __gnu_cxx::__verbose_terminate_handler() + 376
5 libobjc.A.dylib 0x319a2594 _objc_terminate + 104
6 libstdc++.6.dylib 0x301dcdf2 __cxxabiv1::__terminate(void (*)()) + 46
7 libstdc++.6.dylib 0x301dce46 std::terminate() + 10
8 libstdc++.6.dylib 0x301dcf16 __cxa_throw + 78
9 libobjc.A.dylib 0x319a14c4 objc_exception_throw + 64
10 CoreData 0x3526e83e -[NSManagedObjectContext save:] + 1098
11 Wine Brain 0x0000651e 0x1000 + 21790
12 Wine Brain 0x0000525c 0x1000 + 16988
13 Wine Brain 0x00004894 0x1000 + 14484
14 Wine Brain 0x00008716 0x1000 + 30486
15 CoreFoundation 0x31477fe6 -[NSObject(NSObject) performSelector:withObject:withObject:] + 18
16 UIKit 0x338c14a6 -[UIApplication sendAction:to:from:forEvent:] + 78
17 UIKit 0x3395c7ae -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 86
18 CoreFoundation 0x31477fe6 -[NSObject(NSObject) performSelector:withObject:withObject:] + 18
19 UIKit 0x338c14a6 -[UIApplication sendAction:to:from:forEvent:] + 78
20 UIKit 0x338c1446 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 26
21 UIKit 0x338c1418 -[UIControl sendAction:to:forEvent:] + 32
22 UIKit 0x338c116a -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 350
23 UIKit 0x338c19c8 -[UIControl touchesEnded:withEvent:] + 336
24 UIKit 0x338b734e -[UIWindow _sendTouchesForEvent:] + 362
25 UIKit 0x338b6cc8 -[UIWindow sendEvent:] + 256
26 UIKit 0x338a1fc0 -[UIApplication sendEvent:] + 292
27 UIKit 0x338a1900 _UIApplicationHandleEvent + 5084
28 GraphicsServices 0x35d66efc PurpleEventCallback + 660
29 CoreFoundation 0x314656f8 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 20
30 CoreFoundation 0x314656bc __CFRunLoopDoSource1 + 160
31 CoreFoundation 0x31457f76 __CFRunLoopRun + 514
32 CoreFoundation 0x31457c80 CFRunLoopRunSpecific + 224
33 CoreFoundation 0x31457b88 CFRunLoopRunInMode + 52
34 GraphicsServices 0x35d664a4 GSEventRunModal + 108
35 GraphicsServices 0x35d66550 GSEventRun + 56
36 UIKit 0x338d5322 -[UIApplication _run] + 406
37 UIKit 0x338d2e8c UIApplicationMain + 664
38 Wine Brain 0x000021ba 0x1000 + 4538
39 Wine Brain 0x00002184 0x1000 + 4484
I have no idea why my app's memory locations aren't being symbolocated, but the code paths lead to only two manavedObjectContext save: calls. The time this happend, addEntityForType was called all the way through, creating a new object for the "whereTasted" entity, before the final save: on the entire wine object.
When I go through the same procedure again, it works fine. This leads me to believe it's something to do with the app having been run for a while when adding a new location, but I'm not sure.
Any thoughts on how I can debug this and get more info the next time this happens?
put #try - #catch around your save calls. There seems to be an exception thrown while saving:
9 libobjc.A.dylib 0x319a14c4 objc_exception_throw + 64
Sample:
#try
{
if (![self.context save:&error]) {
[[NSApplication sharedApplication] presentError:error];
}
#catch (NSException * e)
{
NSLog(#"exception saving: %#", e);
abort();
}
You should try to activate "Run > Stop on Objective-C exception". It allowed me to find the place where there was an access to an object turned into fault which was the root cause of the problem. (This was advice that recently worked very well for me. Thanks to Kamchatka.)
i use this code to check if any objects exist in my NSMutableArray
if yes i remove them all but it crashes although there are objects why?
if([NSMutableArray1 count]==1)
{
[poemoptionslist removeAllObjects];
}
if ([NSMutableArray1 count]==0)
{
[poemoptionslist addObject: final1];
}
CONSOLE OUTPUT
2010-10-18 03:42:13.166
app1[33398:207] * Terminating app
due to uncaught exception
'NSInternalInconsistencyException',
reason: '-[__NSCFArray
removeObjectAtIndex:]: mutating method
sent to immutable object'
* Call stack at first throw: ( 0 CoreFoundation
0x02e55b99 exceptionPreprocess + 185
1 libobjc.A.dylib
0x02fa540e objc_exception_throw + 47
2 CoreFoundation
0x02e0e238 +[NSException
raise:format:arguments:] + 136 3
CoreFoundation
0x02e0e1aa +[NSException
raise:format:] + 58 4
CoreFoundation
0x02e4d3c1 -[__NSCFArray
removeObjectAtIndex:] + 193 5
CoreFoundation
0x02dfe973 -[NSMutableArray
removeAllObjects] + 83 6
poemsoflove
0x0004dc8d -[submitpoem submitpoem:] +
18560 7 UIKit
0x003b77f8 -[UIApplication
sendAction:to:from:forEvent:] + 119 8
UIKit
0x00442de0 -[UIControl
sendAction:to:forEvent:] + 67 9
UIKit
0x00445262 -[UIControl(Internal)
_sendActionsForEvents:withEvent:] + 527 10 UIKit
0x00443e0f -[UIControl
touchesEnded:withEvent:] + 458 11
UIKit
0x003db3d0 -[UIWindow
_sendTouchesForEvent:] + 567 12 UIKit
0x003bccb4 -[UIApplication sendEvent:]
+ 447 13 UIKit 0x003c19bf _UIApplicationHandleEvent +
7672 14 GraphicsServices
0x033e6822 PurpleEventCallback + 1550
15 CoreFoundation
0x02e36ff4
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION
+ 52 16 CoreFoundation 0x02d97807 __CFRunLoopDoSource1 + 215
17 CoreFoundation
0x02d94a93 __CFRunLoopRun + 979 18
CoreFoundation
0x02d94350 CFRunLoopRunSpecific + 208
19 CoreFoundation
0x02d94271 CFRunLoopRunInMode + 97 20
GraphicsServices
0x033e500c GSEventRunModal + 217 21
GraphicsServices
0x033e50d1 GSEventRun + 115 22 UIKit
0x003c5af2 UIApplicationMain + 1160
23 poemsoflove
0x00002728 main + 102 24 poemsoflove
0x000026b9 start + 53 25 ???
0x00000001 0x0 + 1 ) terminate called
after throwing an instance of
'NSException' Program received signal:
“SIGABRT”.
Guys there is no NSArray!
I save to NSUSerdefaults like this:
if ([mutable1 count]==0)
{
[mutable1 addObject: final1];
}
NSUserDefaults *list =[NSUserDefaults standardUserDefaults];
[list setObject:mutable1 forKey:#"favorites"];
[list synchronize];
and i load data like this
NSUserDefaults *prefs1 =[NSUserDefaults standardUserDefaults];
if ( [prefs1 objectForKey:#"favorites"] != nil)
{
mutable1 = [[NSMutableArray alloc] init];
mutable1 = [prefs1 objectForKey:#"favorites"];
and i get the objects! then when it runs the removeallobjects it crashes!
mutable1 = [[NSMutableArray alloc] init];
mutable1 = [prefs1 objectForKey:#"favorites"];
Even though you've declared mutable1 to be an NSMutableArray, you are reassigning it to the object returned by your NSUserDefaults object. This object is apparently an NSArray rather than an NSMutableArray, hence the crash.
You can load your NSMutableArray with the preferences array by doing something like this:
mutable1 = [[NSMutableArray alloc] init];
[mutable1 addObjectsFromArray:[prefs1 objectForKey:#"favorites"]];
The error messages indicate that you're sending the message to an immutable array, which raises an exception. Uncaught exceptions lead to program termination.
How are you creating the array? The most common error that can lead to this is doing something like:
[mutableArray copy]
Even if the thing you're copying is mutable, the copy will be immutable. In that randomly chosen example, use mutableCopy insted.
Somewhere you have set NSMutableArray1 to an instance of NSArray, not NSMutableArray or you declared NSMutableArray1 as a property of type NSArray vs. NSMutableArray.
Also, you should follow Cocoa / Objective-C naming conventions. Namely, class names start with upper case; variables take the form myArray1 (or something more descriptive, preferably).