Im getting the following exception when attempting to merge a managed context (running on a background thread) with my main managed context (on mainthread). I cant seem to catch the exception in my own #try expression. Does anyone have any insight into this issue?
I'm using the default merge policy but im not sure this is correct - this issue is very intermittent - happens rarely but is causing my app to crash.
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread: 0
Last Exception Backtrace:
0 CoreFoundation 0x37e3b8bf __exceptionPreprocess + 163
1 libobjc.A.dylib 0x319211e5 objc_exception_throw + 33
2 CoreData 0x344b7ea5 -[NSSQLiteStatement cachedSQLiteStatement] + 1
3 CoreData 0x344b774f -[NSSQLiteConnection prepareSQLStatement:] + 55
4 CoreData 0x3455b049 -[NSSQLChannel selectRowsWithCachedStatement:] + 61
5 CoreData 0x34586d63 newFetchedRowsForFetchPlan_MT + 783
6 CoreData 0x344bfb07 -[NSSQLCore newRowsForFetchPlan:] + 351
7 CoreData 0x34565011 -[NSSQLCore fetchRowForObjectID:] + 1005
8 CoreData 0x344d1a57 -[NSSQLCore newValuesForObjectWithID:withContext:error:] + 195
9 CoreData 0x344d0f83 _PFFaultHandlerLookupRow + 423
10 CoreData 0x3450e111 -[NSFaultHandler fulfillFault:withContext:] + 25
11 CoreData 0x34518999 -[NSManagedObject(_NSInternalMethods) _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:] + 77
12 CoreData 0x345178ef -[NSManagedObject(_NSInternalMethods) _newAllPropertiesWithRelationshipFaultsIntact__] + 79
13 CoreData 0x345284db -[NSManagedObjectContext(_NSInternalChangeProcessing) _establishEventSnapshotsForObject:] + 47
14 CoreData 0x3452694b -[NSManagedObjectContext deleteObject:] + 155
15 CoreData 0x345238a1 -[NSManagedObjectContext _mergeChangesFromDidSaveDictionary:usingObjectIDs:] + 813
16 CoreData 0x34522c35 -[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:] + 189
17 myapp 0x0008f0e9 0x8d000 + 8425
18 CoreFoundation 0x37d9a22b -[NSObject performSelector:withObject:] + 43
19 Foundation 0x31d75757 __NSThreadPerformPerform + 351
20 CoreFoundation 0x37e0fb03 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
21 CoreFoundation 0x37e0f2cf __CFRunLoopDoSources0 + 215
22 CoreFoundation 0x37e0e075 __CFRunLoopRun + 653
23 CoreFoundation 0x37d914dd CFRunLoopRunSpecific + 301
24 CoreFoundation 0x37d913a5 CFRunLoopRunInMode + 105
25 GraphicsServices 0x3790ffcd GSEventRunModal + 157
26 UIKit 0x35221743 UIApplicationMain + 1091
I init the background context in start() of a nsoperation like so:
AppDelegate *appController = [[UIApplication sharedApplication] delegate];
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[appController setPersistentStore:_managedObjectContext];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receivedDeletedObjects:) name:NSManagedObjectContextDidSaveNotification object:_managedObjectContext];
I also set up a notification event which is called when objects are deleted on the background managed context, the callback then does:
-(void)receivedDeletedObjects:(NSNotification *)note
{
AppDelegate *appController = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *mainContext = [self managedObjectContext];
[mainContext performSelectorOnMainThread:#selector(mergeChangesFromContextDidSaveNotification:) withObject:note waitUntilDone:NO];
}
Thats pretty much the code. I have 4 different background threads each with its own managed context doing the same thing merging with the main context in this manner. Im wondering multiple threads are getting into mergeChangesFromContextDidSaveNotification at the same time but this shouldnt be the case as it is always called on the mainthread.
How about this:
(all in AppDelegate, call freshContextForBackgroundTask from a background Thread and use save: to trigger the merge.) Note syncObj is a plain NSObject instance needed for synchronization within the app delegate when using many background threads (or just have bad luck with scheduling)
-(NSManagedObjectContext*) freshContextForBackgroundTask {
#synchronized(syncObj) {
NSManagedObjectContext* r = [[NSManagedObjectContext alloc] init];
[r setPersistentStoreCoordinator:self.managedObjectContext.persistentStoreCoordinator];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(backgroundContextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:r];
return r;
}
}
- (void)backgroundContextDidSave:(NSNotification *)notification {
/* Make sure we're on the main thread when updating the main context */
//NSLog(#"merging change: %#",notification);
dispatch_async(dispatch_get_main_queue(), ^{
NSManagedObjectContext *context = [self managedObjectContext];
// this for loop may not be needed for your purpose.
for(NSManagedObject *object in [[notification userInfo] objectForKey:NSUpdatedObjectsKey]) {
[[context objectWithID:[object objectID]] willAccessValueForKey:nil];
}
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
});
}
Your approach seems strange. Especially when you set your app delegate's persistent store to the (nil) one of the freshly init'ed context.
Related
I am using a UINavigationController as rootviewController and storyboard segue for pushingViewController. I have many viewcontrollers in my app. I pass them using push view controller only.
Crash scenario: (can reproduce)
I have a Products list viewController and I will navigate to products detail viewController when I tap on product in the list using tap Gesture recognizer.
From the detail view controller, I will be pushed to cart item viewController which displays all selected products when I tap a button named 'Addd to cart'.
If I try to pay for all the products I want to choose a contact from the people picker, when I press pay button, it will present peopelpickerController as modalViewController and when I choose a contact it gets crashed.
Crash occurs only when move to and fro from products list view controlelr to peoplepicker contoller. When I debugged using instrument I got crash saying deallocated instance receiving message.
I have included the method where I am getting crash. But i never tried to call the method from any controller.
Code...
//choosing contact and people picker delegate
- (IBAction) chooseContacts: (id) sender {
picker = [
[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentViewController: picker animated: YES completion: nil];
}
#pragma mark - Addressbook delegate methods
- (void) peoplePickerNavigationControllerDidCancel: (ABPeoplePickerNavigationController * ) peoplePicker {
[self dismissViewControllerAnimated: YES completion: nil];
}
- (BOOL) peoplePickerNavigationController: (ABPeoplePickerNavigationController * ) peoplePicker
shouldContinueAfterSelectingPerson: (ABRecordRef) person {
[self dismissViewControllerAnimated: YES completion: ^ {
[self displayPerson: person];
}];
return NO;
}
Crash occurs in the below method at the line performSegueWithIdentifier,
#pragma mark- Tap gesture delegates
-(void)tapGestureFirstImage:(UITapGestureRecognizer *)sender
{
UIImageView *image = (UIImageView *)sender.view;
if (image.tag < [_productsArray count]) {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
productDetailDictionary = [_productsArray objectAtIndex:image.tag];
NSLog(#"%#",productDetailDictionary);
[self performSegueWithIdentifier:#"productDetailSeague" sender:sender];
}
NSLog(#"imageView.Tag %ld",(long)image.tag);
}
Crash Log:
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Triggered by Thread: 0
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x39cb11fc __pthread_kill + 8
1 libsystem_pthread.dylib 0x39d1aa2e pthread_kill + 54
2 libsystem_c.dylib 0x39c61ff8 abort + 72
3 libc++abi.dylib 0x38f90cd2 abort_message + 70
4 libc++abi.dylib 0x38fa96e0 default_terminate_handler() + 248
5 libobjc.A.dylib 0x396f291e _objc_terminate() + 190
6 libc++abi.dylib 0x38fa71c4 std::__terminate(void (*)()) + 76
7 libc++abi.dylib 0x38fa6a18 __cxa_throw + 112
8 libobjc.A.dylib 0x396f277e objc_exception_throw + 246
9 CoreFoundation 0x2ef5be88 +[NSException raise:format:] + 100
10 UIKit 0x317b9590 -[UIViewController _preferredInterfaceOrientationForPresentationInWindow:fromInterfaceOrientation:] + 496
11 UIKit 0x317b7dce -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:animation:] + 2054
12 UIKit 0x317b6e20 -[UIViewController presentViewController:withTransition:completion:] + 4664
13 UIKit 0x31992cae -[UIViewController presentModalViewController:animated:] + 26
14 DHCC Events 0x0008f0c0 0x38000 + 356544
15 libdispatch.dylib 0x39bd5d18 _dispatch_call_block_and_release + 8
16 libdispatch.dylib 0x39bdbd16 _dispatch_after_timer_callback$VARIANT$mp + 46
17 libdispatch.dylib 0x39bd5d04 _dispatch_client_callout + 20
18 libdispatch.dylib 0x39bde7fe _dispatch_source_invoke$VARIANT$mp + 258
19 libdispatch.dylib 0x39bdc73a _dispatch_main_queue_callback_4CF$VARIANT$mp + 186
20 CoreFoundation 0x2ef26814 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 4
21 CoreFoundation 0x2ef250e8 __CFRunLoopRun + 1296
22 CoreFoundation 0x2ee8fc22 CFRunLoopRunSpecific + 518
23 CoreFoundation 0x2ee8fa06 CFRunLoopRunInMode + 102
24 GraphicsServices 0x33b8327e GSEventRunModal + 134
25 UIKit 0x31733044 UIApplicationMain + 1132
26 DHCC Events 0x00041ad6 0x38000 + 39638
27 libdyld.dylib 0x39bfaab4 start + 0
Appreciate your help.
On -(void)tapGestureFirstImage:(UITapGestureRecognizer *)sender
you perform the segue with
[self performSegueWithIdentifier:#"productDetailSeague" sender:sender];
but I think the sender should be self and not sender..
UPDATE
Do you try to perform segue while picker is active? In this case self may be deallocated, so you can try to perform segue after picker is dismissed:
[picker dismissViewControllerAnimated:YES completion:^{[self performSegueWithIdentifier:#"productDetailSeague" sender:self];}];
I developing an application that application well worked for me my XCode version is 4.2.1 and iOS version is 5.0 ARC enable code. My process is i showing a bunch of YouTube videos in tableview using web service. I cache those video Icon in my directory. When i sending that application for apple review... application going crash there, the crash report is following,
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread: 2
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet bytes]: unrecognized selector sent to instance 0x27b300'
*** First throw call stack:
(0x3502e88f 0x36455259 0x35031a9b 0x35030915 0x34f8b650 0x34f7da4d 0x3587f2b9 0x3587ef31 0x3587ee9d 0x321102ab 0x321101c7 0xe36dd 0x31053c59 0x3105f7bb 0x36cd9dfb 0x36cd9cd0)
Thread 2 name: Dispatch queue: com.apple.root.default-priority
Thread 2 Crashed:
0 libsystem_kernel.dylib 0x34e2232c __pthread_kill + 8
1 libsystem_c.dylib 0x36d1e208 pthread_kill + 48
2 libsystem_c.dylib 0x36d17298 abort + 88
3 libc++abi.dylib 0x309e3f64 abort_message + 40
4 libc++abi.dylib 0x309e1346 _ZL17default_terminatev + 18
5 libobjc.A.dylib 0x36455350 _objc_terminate + 140
6 libc++abi.dylib 0x309e13be _ZL19safe_handler_callerPFvvE + 70
7 libc++abi.dylib 0x309e144a std::terminate() + 14
8 libc++abi.dylib 0x309e2798 __cxa_throw + 116
9 libobjc.A.dylib 0x36455290 objc_exception_throw + 88
10 CoreFoundation 0x35031a94 -[NSObject doesNotRecognizeSelector:] + 168
11 CoreFoundation 0x3503090e ___forwarding___ + 294
12 CoreFoundation 0x34f8b648 _CF_forwarding_prep_0 + 40
13 CoreFoundation 0x34f7da46 CFDataGetBytePtr + 90
14 ImageIO 0x3587f2b2 CGImageReadGetBytePointer + 30
15 ImageIO 0x3587ef2a _CGImageSourceBindToPlugin + 86
16 ImageIO 0x3587ee96 CGImageSourceGetCount + 50
17 UIKit 0x321102a4 _UIImageRefFromData + 124
18 UIKit 0x321101c0 -[UIImage initWithData:] + 52
19 MyAppName 0x000e36d6 __37-[JMImageCache imageForURL:delegate:]_block_invoke_0 + 142
20 libdispatch.dylib 0x31053c52 _dispatch_call_block_and_release + 6
21 libdispatch.dylib 0x3105f7b4 _dispatch_worker_thread2 + 256
22 libsystem_c.dylib 0x36cd9df4 _pthread_wqthread + 288
23 libsystem_c.dylib 0x36cd9cc8 start_wqthread + 0
Now my coding part in application ,
On Table view data source method
if(![[JMImageCache sharedCache] isImageExistInCache: cell.videoThumbnailImageLink]){
[cell.activityIndicator startAnimating];
cell.videoThumbnail.image = [[JMImageCache sharedCache] imageForURL:cell.videoThumbnailImageLink delegate:cell];
}
else{
[cell.activityIndicator stopAnimating];
[cell.activityIndicator removeFromSuperview];
cell.videoThumbnail.image = [[JMImageCache sharedCache] imageFromDiskForURL:cell.videoThumbnailImageLink];
}
And at custom cell of that tableview,
#pragma mark - JMImageCacheDelegate Methods
- (void) cache:(JMImageCache *)c didDownloadImage:(UIImage *)i forURL:(NSString *)url {
if([url isEqualToString:self.videoThumbnailImageLink]) {
self.imageView.image = i;
[self setNeedsLayout];
}
[self.activityIndicator stopAnimating];
[self.activityIndicator removeFromSuperview];
}
In JMImageCache library code block,
- (UIImage *) imageForURL:(NSString *)url delegate:(id<JMImageCacheDelegate>)d {
if(!url) {
return nil;
}
id returner = [super objectForKey:url];
if(returner) {
return returner;
} else {
UIImage *i = [self imageFromDiskForURL:url];
if(i) {
[self setImage:i forURL:url];
return i;
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
__unsafe_unretained NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
UIImage *i = [[UIImage alloc] initWithData:data];
__unsafe_unretained NSString* cachePath = cachePathForURL(url);
NSInvocation* writeInvocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:#selector(writeData:toPath:)]];
[writeInvocation setTarget:self];
[writeInvocation setSelector:#selector(writeData:toPath:)];
[writeInvocation setArgument:&data atIndex:2];
[writeInvocation setArgument:&cachePath atIndex:3];
[self performDiskWriteOperation:writeInvocation];
[self setImage:i forURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
if(d) {
if([d respondsToSelector:#selector(cache:didDownloadImage:forURL:)]) {
[d cache:self didDownloadImage:i forURL:url];
}
}
});
});
return nil;
}
}
Thanks.
You have a memory problem. The hint is, that the variable which points to 0x27b300 in memory now contains a __NSCFSet (otherwise known as an NSSet). Make sure you're not using a variable which hasn't been nil'd out or is weak when it should be strong.
Your data is being released and deallocated before it's used, so when CoreGraphics calls -bytes on it, it's no longer there (and in this case, an NSSet has been allocated in its place).
Presumably this is because you declared it as __unsafe_unretained.
I use UIWebView to load this site http://www.xiami.com/song/1024665
sometimes my app crashes if I touch the view or play the audio in this site and sometimes it does not, why?
is it because html5? how to solve?
other website is no problem.
crash log is
* -[MPTransportButton _isChargeEnabled]: message sent to deallocated instance 0x20aa58d0
any help is much appreciated
---update---
I create a new view-base project, the code in ViewController is as following
This time, the crash log is
2011-08-16 18:11:25.450 WebTest[1291:707] -[__NSCFDictionary _isChargeEnabled]: unrecognized selector sent to instance 0x1ede0a10
2011-08-16 18:11:25.462 WebTest[1291:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary _isChargeEnabled]: unrecognized selector sent to instance 0x1ede0a10'
*** Call stack at first throw:
(
0 CoreFoundation 0x30ea764f __exceptionPreprocess + 114
1 libobjc.A.dylib 0x349c2c5d objc_exception_throw + 24
2 CoreFoundation 0x30eab1bf -[NSObject(NSObject) doesNotRecognizeSelector:] + 102
3 CoreFoundation 0x30eaa649 ___forwarding___ + 508
4 CoreFoundation 0x30e21180 _CF_forwarding_prep_0 + 48
5 UIKit 0x30f232bd -[UIWindow warpPoint:] + 200
6 UIKit 0x30f0c1d5 _UIApplicationHandleEvent + 2404
7 GraphicsServices 0x30790e77 PurpleEventCallback + 666
8 CoreFoundation 0x30e7ea97 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
9 CoreFoundation 0x30e8083f __CFRunLoopDoSource1 + 166
10 CoreFoundation 0x30e8160d __CFRunLoopRun + 520
11 CoreFoundation 0x30e11ec3 CFRunLoopRunSpecific + 230
12 CoreFoundation 0x30e11dcb CFRunLoopRunInMode + 58
13 GraphicsServices 0x3079041f GSEventRunModal + 114
14 GraphicsServices 0x307904cb GSEventRun + 62
15 UIKit 0x30f37d69 -[UIApplication _run] + 404
16 UIKit 0x30f35807 UIApplicationMain + 670
17 WebTest 0x00013425 main + 48
18 WebTest 0x000133f0 start + 40
)
terminate called after throwing an instance of 'NSException'
the source code in the project, not use MPMoviePlayerController this time or something else
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [self init];
return self;
}
- (id)init
{
if (self = [super initWithNibName:nil bundle:nil])
{
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIWebView *web = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
[web loadRequest:[NSURLRequest requestWithURL:
[NSURL URLWithString:#"http://www.xiami.com/song/1024665"]]];
web.delegate = self;
[self.view addSubview:web];
[web release];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
//[webView stringByEvaluatingJavaScriptFromString:#"window.scrollTo(0, 10);"];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
}
There's nothing wrong in code that you posted.
NSZombie says that there is a MPTransportButton somewhere in your code that was previously deallocated (released) and after that, somewhere else in your code, you want to do something with it.
I think that you do it in one of your UIWebView's delegate methods.
But... we need more code. Where do you alloc/init your MPMoviePlayerController? Or do you alloc/init a MPTransportButton?
I have this crash. It is similar to other threads, but not the same.
I would like to show a modal view controller first the user goes to a specific view controller. Following the hints, I do that on - (void) viewDidAppear:(BOOL)animated, and apply a delay as I saw it's recommended.
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self performSelector:#selector(presentMyModal) withObject:nil afterDelay:1];
}
- (void) presentModal{
ModalViewController *modal = [[[ModalViewController alloc] init] autorelease];
[self presentModalViewController:modal animated:YES];
}
Afterwards, ramdomly It crashes. I get this message in console:
<Warning>: *** Assertion failure in -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:], /SourceCache/UIKit/UIKit-1447.6.4/UIWindowController.m:186
Thu Feb 3 10:00:44 unknown MyApp[1830] <Error>: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempting to begin a modal transition from <UINavigationController: 0x454260> to <ModalViewController: 0x47af00> while a transition is already in progress. Wait for viewDidAppear/viewDidDisappear to know the current transition has completed'
*** Call stack at first throw:
(
0 CoreFoundation 0x3759dc7b __exceptionPreprocess + 114
1 libobjc.A.dylib 0x32d9bee8 objc_exception_throw + 40
2 CoreFoundation 0x3759dac3 +[NSException raise:format:arguments:] + 70
3 Foundation 0x351a3e73 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 62
4 UIKit 0x359e92a8 -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 208
5 UIKit 0x359e8c98 -[UIViewController presentModalViewController:withTransition:] + 2792
6 UIKit 0x35a7b51c -[UIViewController _tryRecursivelyPresentModalViewController:withTransition:] + 116
7 UIKit 0x359e84c0 -[UIViewController presentModalViewController:withTransition:] + 784
8 UIKit 0x359e8060 -[UIViewController presentModalViewController:animated:] + 96
9 MyApp 0x0005d57f -[MyAppViewController presentMyModal] + 58
10 Foundation 0x351724db __NSFireDelayedPerform + 366
11 CoreFoundation 0x37552305 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 16
12 CoreFoundation 0x37551cd9 __CFRunLoopDoTimer + 988
13 CoreFoundation 0x37521a91 __CFRunLoopRun + 1184
14 CoreFoundation 0x3752150b CFRunLoopRunSpecific + 226
15 CoreFoundation 0x37521419 CFRunLoopRunInMode + 60
16 GraphicsServices 0x33e76d24 GSEventRunModal + 196
17 UIKit 0x3591d57c -[UIApplication _run] + 588
18 UIKit 0x3591a558 UIApplicationMain + 972
19 MyApp 0x0000e75f main + 50
20 MyApp 0x0000e6e8 start + 52
As you can see, I wait until view is appeared. Is this maybe an OS bug? It seems like it tries to present recursively other modal view controllers, provoquing crashes.
Thanks a lot.
Apart from me being picky in the comment, I thought I could as well help with this one as well. I think you need to search for the culprit somewhere else. I created a new project and a view controller with this snippet:
#import "VC1.h"
#implementation VC1
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self performSelector:#selector(presentModal) withObject:nil afterDelay:1.0];
}
- (void)presentModal {
static int colorChooser = 0;
VC1 *vc1 = [[[VC1 alloc] init] autorelease];
switch (colorChooser%2) {
case 0:
vc1.view.backgroundColor = [UIColor whiteColor];
break;
default:
vc1.view.backgroundColor = [UIColor blackColor];
break;
}
colorChooser++;
[self presentModalViewController:vc1 animated:YES];
}
#end
And it works flawlessly after being pushed on the navigation controller. It is recursively alternating between black and white views, tested both in the sim and on a 3G device.
Maybe you are doing some other view transitions due to some notifications or other asynchronic means? Either way you would need to share more of your code for anyone to tell where the problem is.
Our preferred solution is to use -[UIViewController presentViewController:animated:completion:] and do whatever the next action is (eg presenting another VC) in the completion block.
For example:
[self presentViewController:yourViewController animated:YES completion:^{
[yourViewController presentMyModal];
}];
This method was introduced in iOS 5.0.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Thread" inManagedObjectContext:managedObjectContext];
That line doesn't seem to work anymore (I'm pretty sure its that line).
I can't seem to work out whats the problem. The application worked perfectly on Xcode with iOS 4.1 and now crashes with this error in the console:
2010-12-07 17:12:27.552 SMSApp[9222:207] +[ persistentStoreCoordinator]: unrecognized selector sent to class 0x5b14580
2010-12-07 17:12:27.553 SMSApp[9222:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[ persistentStoreCoordinator]: unrecognized selector sent to class 0x5b14580'
*** Call stack at first throw:
(
0 CoreFoundation 0x01547be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0169c5c2 objc_exception_throw + 47
2 CoreFoundation 0x015497bb +[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x014b9366 ___forwarding___ + 966
4 CoreFoundation 0x014b8f22 _CF_forwarding_prep_0 + 50
5 CoreData 0x00e6f3ca +[NSEntityDescription entityForName:inManagedObjectContext:] + 42
6 SMSApp 0x000046b9 -[MessagesRootViewController reloadMessages:] + 146
7 SMSApp 0x00004a09 -[MessagesRootViewController viewDidLoad] + 85
8 UIKit 0x0052265e -[UIViewController view] + 179
9 UIKit 0x00520a57 -[UIViewController contentScrollView] + 42
10 UIKit 0x00531201 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 48
11 UIKit 0x0052f831 -[UINavigationController _layoutViewController:] + 43
12 UIKit 0x00530b4c -[UINavigationController _startTransition:fromViewController:toViewController:] + 524
13 UIKit 0x0052b606 -[UINavigationController _startDeferredTransitionIfNeeded] + 266
14 UIKit 0x00643e01 -[UILayoutContainerView layoutSubviews] + 226
15 QuartzCore 0x010b4451 -[CALayer layoutSublayers] + 181
16 QuartzCore 0x010b417c CALayerLayoutIfNeeded + 220
17 QuartzCore 0x010ad37c _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310
18 QuartzCore 0x010ad0d0 _ZN2CA11Transaction6commitEv + 292
19 UIKit 0x0047719f -[UIApplication _reportAppLaunchFinished] + 39
20 UIKit 0x00477659 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 690
21 UIKit 0x00481db2 -[UIApplication handleEvent:withNewEvent:] + 1533
22 UIKit 0x0047a202 -[UIApplication sendEvent:] + 71
23 UIKit 0x0047f732 _UIApplicationHandleEvent + 7576
24 GraphicsServices 0x01b2ca36 PurpleEventCallback + 1550
25 CoreFoundation 0x01529064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
26 CoreFoundation 0x014896f7 __CFRunLoopDoSource1 + 215
27 CoreFoundation 0x01486983 __CFRunLoopRun + 979
28 CoreFoundation 0x01486240 CFRunLoopRunSpecific + 208
29 CoreFoundation 0x01486161 CFRunLoopRunInMode + 97
30 UIKit 0x00476fa8 -[UIApplication _run] + 636
31 UIKit 0x0048342e UIApplicationMain + 1160
32 SMSApp 0x000025c4 main + 102
33 SMSApp 0x00002555 start + 53
)
terminate called after throwing an instance of 'NSException'
Any idea where this error is coming from or what is causing it?
Just to let you know as well, upgrading to XCode with iOS 4.2 caused some of the files to be deleted from my project. I don't know why this was, whether it was because they were linked files and not actually in the folder I dunno.
Any ideas?
Thanks
// EDIT
This method is in the AppDelegate:
- (NSManagedObjectContext *)managedObjectContext {
if (managedObjectContext_ != nil) {
return managedObjectContext_;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext_ = [[NSManagedObjectContext alloc] init];
[managedObjectContext_ setPersistentStoreCoordinator:coordinator];
}
return managedObjectContext_;
}
// EDIT AGAIN
- (void)reloadMessages:(NSNotification *)notification {
NSLog(#"RECIEVED NEW MESSAGES TO MessagesRootViewController");
NSLog(#"%#",managedObjectContext);
// we need to get the threads from the database...
NSFetchRequest *theReq = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Thread" inManagedObjectContext:self.managedObjectContext];
[theReq setEntity:entity];
threads = [NSArray arrayWithArray:[managedObjectContext executeFetchRequest:theReq error:nil]];
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
if(notification != nil){ // if its been caused by a notification
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"New Message" message:#"A new message has been received" delegate:nil cancelButtonTitle:#"Thanks" otherButtonTitles:nil];
[alert performSelectorOnMainThread:#selector(show) withObject:nil waitUntilDone:NO];
[alert release];
}
}
// EDIT 3
If I put this code in the applicationDidFinishLoading of my app delegate it works fine!
NSFetchRequest *theReq = [[NSFetchRequest alloc] init];
NSEntityDescription *theEntity = [NSEntityDescription entityForName:#"Thread" inManagedObjectContext:self.managedObjectContext];
[theReq setEntity:theEntity];
NSArray *theThreads = [NSArray arrayWithArray:[self.managedObjectContext executeFetchRequest:theReq error:nil]];
After having a quick look at your code I think I found a couple of parts that needed attention. I'll try and break them down below:
SMSAppAppDelegate
1) Notice that in your interface file, you declare your CoreData variables with an underscore at the end of the variable name. Then you create properties for each of the ivar without the underscore. That is all fine as long as you #synthesize them making the correct assignment, which seems to be missing from your implementation:
#synthesize managedObjectContext=managedObjectContext_;
#synthesize managedObjectModel=managedObjectModel_;
#synthesize persistentStoreCoordinator=persistentStoreCoordinator_;
DownloadContacts
1) In this class you are calling the managedObjectContext directly through the variable. I wouldn't recommend that but this is not your actual problem. Notice that you release the managedObjectContext on dealloc even though you have no ownership of it!
2) What I would do in this case is declare a property for the context and always access it via the property. Also if you rename your instance variable to include an underscore at the end you are minimising your chances of accessing it directly (i.e. without using self.) and it will make it easier for you to find where in this class you are actually doing that (there are a couple of places from memory).
So in your interface file, rename managedObjectContext ivar and declare a property:
NSManagedObjectContext *managedObjectContext_;
...
#property (nonatomic, retain) NSManagedObjectContext managedObjectContext;
And don't forget to make the assignment on #sythesize and release on dealloc, since you are using a retain property:
#synthesize managedObjectContext=managedObjectContext_;
...
[managedObjectContext_ release];
Then if you try and compile you will get two or three errors of unrecognised instance variable which is where you have to go and change it to self.managedObjectContext
MessagesRootViewController
And finally I'd recommend you go through the same process in your MessagesRootViewController but this one should still work fine as is!
See how you go and let me know if any of the above is not clear!
Cheers,
Rog
I'm assuming you're doing something like:
[ClassName persistentStoreCoordinator]
Make sure ClassName is defined and has the persistentStoreCoordinator class method. Perhaps the file that did these things got deleted?
Matt
Your database might be corrupted, try resetting the iOS simulator
by clicking on iOS Simulator>Reset contents and settings.
Edit:
It looks like you're trying to call a selector that doesn't exist. Try figuring out which files were deleted, as it seems like you have a method that is called that can't be found at runtime. Did your core data classes get erased, maybe?