Reputation: 64854
I'm getting a Out of Bounds exception in iOS4, which I don't get when I run my app in iOS5.
I get the exception when I invoke executeFetchRequest:error:
This is the code:
// Fetch
NSPredicate *pred = [NSPredicate predicateWithFormat:@"DisplayName = %@", inDisplayName];
//iOS5 only
//NSFetchRequest *req = [[NSFetchRequest alloc] initWithEntityName:inEntityName];
NSFetchRequest *req = [[NSFetchRequest alloc] init];
[req setEntity:[NSEntityDescription entityForName:inEntityName inManagedObjectContext:inContext]];
[req setFetchLimit:1];
[req setPropertiesToFetch:[NSArray arrayWithObject:@"DisplayName"]];
[req setIncludesPropertyValues:NO];
[req setIncludesSubentities:NO];
[req setPredicate:pred];
NSError *err = nil;
NSArray * results = [inContext executeFetchRequest:req error:&err]; // here
if ([results count]) {
id result = [results objectAtIndex:0];
[cache setObject:result forKey:cacheKey];
return result;
}
FreeAndNil(req);
And this is the log:
2012-08-23 10:47:35.855 MyApp [2694:11603] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 4294967295 beyond bounds [0 .. 30]'
*** Call stack at first throw:
(
0 CoreFoundation 0x01cb15a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x02035313 objc_exception_throw + 44
2 CoreFoundation 0x01ca70a5 -[__NSArrayM objectAtIndex:] + 261
3 CoreFoundation 0x01bd674e CFArrayGetValueAtIndex + 190
4 CoreData 0x0193c304 -[NSSQLCore _prepareDictionaryResultsFromResultSet:usingFetchPlan:] + 2084
5 CoreData 0x018867ac -[NSSQLCore _newRowsForFetchPlan:selectedBy:withArgument:] + 2188
6 CoreData 0x0187d151 -[NSSQLCore newRowsForFetchPlan:] + 369
7 CoreData 0x0187c515 -[NSSQLCore objectsForFetchRequest:inContext:] + 357
8 CoreData 0x0187c0ce -[NSSQLCore executeRequest:withContext:error:] + 206
9 CoreData 0x0192bcdc -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 1084
10 CoreData 0x01879267 -[NSManagedObjectContext executeFetchRequest:error:] + 359
11 MyApp 0x0002519a +[CMItem objectWithEntityName:displayNameHasValue:inContext:] + 666
12 MyApp 0x00024c50 +[CMItem objectWithEntityName:andProperty:hasValue:inContext:] + 208
13 MyApp 0x00051ba7 -[CMMyEntity awakeFromInsert] + 295
14 CoreData 0x018b0647 -[NSManagedObjectContext insertObject:] + 151
15 CoreData 0x0188c680 -[NSManagedObject initWithEntity:insertIntoManagedObjectContext:] + 336
16 CoreData 0x018b0a33 +[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:] + 131
17 MyApp 0x000909a4 -[CMEditViewControllerBase loadNewCollectible] + 212
18 MyApp 0x00091756 -[CMEditViewControllerBase saveButtonPushed:] + 614
19 UIKit 0x007204fd -[UIApplication sendAction:to:from:forEvent:] + 119
20 UIKit 0x00932cc3 -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 156
21 UIKit 0x007204fd -[UIApplication sendAction:to:from:forEvent:] + 119
22 UIKit 0x007b0799 -[UIControl sendAction:to:forEvent:] + 67
23 UIKit 0x007b2c2b -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
24 UIKit 0x007b17d8 -[UIControl touchesEnded:withEvent:] + 458
25 UIKit 0x00744ded -[UIWindow _sendTouchesForEvent:] + 567
26 UIKit 0x00725c37 -[UIApplication sendEvent:] + 447
27 UIKit 0x0072af2e _UIApplicationHandleEvent + 7576
28 GraphicsServices 0x0244a992 PurpleEventCallback + 1550
29 CoreFoundation 0x01c92944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
30 CoreFoundation 0x01bf2cf7 __CFRunLoopDoSource1 + 215
31 CoreFoundation 0x01beff83 __CFRunLoopRun + 979
32 CoreFoundation 0x01bef840 CFRunLoopRunSpecific + 208
33 CoreFoundation 0x01bef761 CFRunLoopRunInMode + 97
34 GraphicsServices 0x024491c4 GSEventRunModal + 217
35 GraphicsServices 0x02449289 GSEventRun + 115
36 UIKit 0x0072ec93 UIApplicationMain + 1160
thanks
UPDATE:
- (void)awakeFromInsert
{
[super awakeFromInsert];
[self setReadIt:[NSNumber numberWithBool:YES]];
[self setCLZID:@"0"];
CMLookUpItemComic *myRating = [CMItem objectWithEntityName:@"MyRating" andProperty:@"DisplayName" hasValue:@"0" inContext:[self managedObjectContext]];
[self setMyRating:myRating];
[self setUserValues:[NSEntityDescription insertNewObjectForEntityForName:@"UserValues" inManagedObjectContext:[self managedObjectContext]]];
}
Superclass:
- (void)awakeFromInsert
{
[super awakeFromInsert];
[self autoSetUniqueID];
}
- (void)autoSetUniqueID
{
if (highestUniqueID == NSNotFound) {
NSManagedObjectContext *context = [self managedObjectContext];
NSEntityDescription *entity = [self entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"UniqueID"
ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:sort];
[sort release];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
[fetch setEntity:entity];
[fetch setFetchLimit:1];
[fetch setSortDescriptors:sortDescriptors];
NSArray *results = [context executeFetchRequest:fetch error:nil];
[fetch release];
if (results != nil && [results count]) {
CMItem *itemWithHighestID = [results lastObject];
highestUniqueID = [[itemWithHighestID UniqueID] integerValue];
} else {
highestUniqueID = 0;
}
}
highestUniqueID++;
[self setPrimitiveValue:[NSNumber numberWithInt:highestUniqueID] forKey:@"UniqueID"];
}
Upvotes: 1
Views: 530
Reputation: 64854
For anyone getting into this issue and losing all day like me:
NSPredicate *pred = [NSPredicate predicateWithFormat:@"DisplayName = \"%@\"", inDisplayName];
The crash was caused by the missing brackets \"%@\"
in the predicate/
Upvotes: 3
Reputation: 10633
What you have done makes me very nervous. From the Apple Docs:
You are typically discouraged from performing fetches within an implementation of awakeFromInsert. Although it is allowed, execution of the fetch request can trigger the sending of internal Core Data notifications which may have unwanted side-effects. For example, in OS X, an instance of NSArrayController may end up inserting a new object into its content array twice.
My suggestion is to remove the -awakeFromInsert code completely, and make highestUniqueID a transient property that is calculated each time it is required. You can retrieve the maximum value for a property very efficiently using Core Data. Read the section titled Fetching Specific Values.
You are trying to recreate the objectID. There is no reason for this code.
Upvotes: 0