Memory management error on persistent store error - ios

I am getting an error that seems pretty clearly to be a message to a deallocated object, but I cannot figure out where I am managing memory wrong. This is my code to create the persistent store coordinator. It's based on the Core Data application template. I might have changed it a bit, but not much I think.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
/* Reminder: in Simulator this is in /Users/<username>/Library/Application Support/iPhone Simulator/User/Applications/<bundleid>/Documents/Wordfare.sqlite */
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: #"Wordfare.sqlite"]];
NSError *error;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
[persistentStoreCoordinator release];
persistentStoreCoordinator = nil;
}
return persistentStoreCoordinator;
}
The problem happens when I get an error from addPersistentStore, because I changed my model and I'm trying to open a store that was created with the previous model. Of course one answer is, "Don't do that." I won't, but I want the code to be robust. The above code runs without complaint, but then when I press the home button, the app crashes with this error:
2011-11-02 16:39:53.751 Wordfare[11137:207] -[__NSCFArray tryLock]: unrecognized selector sent to instance 0x5a122f0
2011-11-02 16:39:53.783 Wordfare[11137:207] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray tryLock]: unrecognized selector sent to instance 0x5a122f0'
* Call stack at first throw:
(
0 CoreFoundation 0x012ed5a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x01441313 objc_exception_throw + 44
2 CoreFoundation 0x012ef0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x0125e966 forwarding + 966
4 CoreFoundation 0x0125e522 _CF_forwarding_prep_0 + 50
5 CoreData 0x010d9ef0 -[_NSSQLCoreConnectionObsever _purgeCaches:] + 112
6 Foundation 0x00370669 _nsnote_callback + 145
7 CoreFoundation 0x012c59f9 __CFXNotificationPost_old + 745
8 CoreFoundation 0x0124493a _CFXNotificationPostNotification + 186
9 Foundation 0x0036620e -[NSNotificationCenter postNotificationName:object:userInfo:] + 134
10 UIKit 0x0060aa0b -[UIApplication _handleApplicationSuspend:eventInfo:] + 554
11 UIKit 0x00614039 -[UIApplication handleEvent:withNewEvent:] + 4127
12 UIKit 0x0060babf -[UIApplication sendEvent:] + 71
13 UIKit 0x00610f2e _UIApplicationHandleEvent + 7576
14 GraphicsServices 0x03851992 PurpleEventCallback + 1550
15 CoreFoundation 0x012ce944 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION + 52
16 CoreFoundation 0x0122ecf7 __CFRunLoopDoSource1 + 215
17 CoreFoundation 0x0122bf83 __CFRunLoopRun + 979
18 CoreFoundation 0x0122b840 CFRunLoopRunSpecific + 208
19 CoreFoundation 0x0122b761 CFRunLoopRunInMode + 97
20 GraphicsServices 0x038501c4 GSEventRunModal + 217
21 GraphicsServices 0x03850289 GSEventRun + 115
22 UIKit 0x00614c93 UIApplicationMain + 1160
23 Wordfare 0x00002224 main + 102
24 Wordfare 0x000021b5 start + 53
)
terminate called after throwing an instance of 'NSException'
Sorry for the double-spacing. I couldn't figure out the formatting.
It looks like an __NSCFArray has happened to move in after the persistent store coordinator was deallocated, but something still has a pointer to the persistent store and is trying to call its tryLock.
It's really hard to tell what that could be. I allocate the persistent store coordinator, call addPersistentStore, then release it and set it to nil. Nothing in my code could have got a reference to it outside that method. The only thing I can imagine getting a reference to it would be the managedObjectModel. I tried releasing that too but that got a different error.
If I comment out the line that releases persistentStoreCoordinator, and just set it to nil, then it runs fine, but that can't be right. persistentStoreCoordinator is an instance variable of course. I allocated it; I should release it if I'm discarding the reference to it.
How am I supposed to clean up a persistent store coordinator after an error?
Additional: I have confirmed that the unrecognized selector is getting sent to the memory address of the persistent store coordinator.

Not a Core Data answer, but you should run with zombies enabled (in recent Xcodes, just hit the checkbox in the Debug part of the scheme).

Related

Sporadic Crash Resetting Persistent Stores Between Unit Test Cases (RestKit)

I apologize in advance that this probably won't end up contributing much to the general knowledge base here, but I'm looking for help diagnosing what's likely a configuration oversight that's causing my unit tests to crash sporadically.
I'm set up using RestKit with an in-memory object store while unit testing, so that after each test case, I can reset my persistent stores and each test can run with a fresh database. Much of the time my test suite runs without issue, but often enough to be a deal-breaker, there's a crash from what [I think] appears to be over-releasing a managed object context. All relevant code and crash data below:
Unit Test Base Class Setup
#implementation MyTestCase
- (void)setUp
{
[super setUp];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[[MyObjectManager sharedManager] start];
});
}
- (void)tearDown
{
[super tearDown];
[[MyObjectManager sharedManager] reset];
}
Relevant MyObjectManager Setup
#interface MyObjectManager : RKObjectManager
- (void)start
{
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithPersistentStoreCoordinator:[self persistentStoreCoordinator]];
self.managedObjectStore = managedObjectStore;
[managedObjectStore createManagedObjectContexts];
[RKManagedObjectStore setDefaultStore:managedObjectStore];
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil)
{
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:kRDPersistentStore];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = #{
NSSQLitePragmasOption : #{
#"synchronous" : #"FULL",
#"fullfsync" : #(1)
},
NSMigratePersistentStoresAutomaticallyOption : #YES,
NSInferMappingModelAutomaticallyOption : #YES
};
NSError *error = nil;
if (![self persistentStoreAtPath:storeURL options:options error:error])
{
NSLog(#"Error adding store %#: %#, %#", storeURL, error, [error userInfo]);
// Additional handling
}
return _persistentStoreCoordinator;
}
- (NSPersistentStore *)persistentStoreAtPath:(NSURL *)storeURL options:(NSDictionary *)options error:(NSError *)error
{
// (NSSQLiteStoreType and storeUrl are used if we're not unit testing)
return [_persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType
configuration:nil
URL:nil
options:options
error:&error];
}
MyObjectManager::reset Implementation
- (void)reset
{
[[RKObjectManager sharedManager].operationQueue cancelAllOperations];
NSError *error = nil;
[[RKManagedObjectStore defaultStore] resetPersistentStores:&error];
if (error)
{
NSLog(#"Error! : %#", error);
}
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
Typical Crash Report
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGSEGV)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Application Specific Information:
iPhone Simulator 463.9.41, iPhone OS 7.1 (iPhone Retina (4-inch)/11D167)
Main thread is spinning the run loop, waiting on an asynchronous test case:
(Not always the case but a majority of our tests employ this method)
Thread : com.apple.main-thread
0 libsystem_kernel.dylib 0x047f6f92 semaphore_signal_trap + 10
1 libdispatch.dylib 0x0447f41f _dispatch_barrier_sync_f_slow_invoke + 54
2 libdispatch.dylib 0x044904d0 _dispatch_client_callout + 14
3 libdispatch.dylib 0x0447e726 _dispatch_main_queue_callback_4CF + 340
4 CoreFoundation 0x040fb43e __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 14
5 CoreFoundation 0x0403c5cb __CFRunLoopRun + 1963
6 CoreFoundation 0x0403b9d3 CFRunLoopRunSpecific + 467
7 CoreFoundation 0x0403b7eb CFRunLoopRunInMode + 123
8 Foundation 0x03a71e35 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 284
9 Foundation 0x03a71cd5 -[NSRunLoop(NSRunLoop) runUntilDate:] + 88
10 Remind101-Tests 0x0cbb2c02 -[UTTestCase waitForBlockWithTimeout:] + 233
11 Remind101-Tests 0x0cbb2b14 -[UTTestCase waitForBlock] + 49
12 Remind101-Tests 0x0cbba55e -[UTAPITestCase sendRequestExpectingSuccess:] + 142
13 Remind101-Tests 0x0cb92832 -[UTMessageRequestTests testRequestCreatesFileEntities] + 166
14 CoreFoundation 0x0408a91d __invoking___ + 29
15 CoreFoundation 0x0408a82a -[NSInvocation invoke] + 362
16 XCTest 0x20103c6c -[XCTestCase invokeTest] + 221
17 XCTest 0x20103d7b -[XCTestCase performTest:] + 111
18 otest-shim-ios.dylib 0x0098fcc7 XCPerformTestWithSuppressedExpectedAssertionFailures + 172
19 otest-shim-ios.dylib 0x0098fc15 XCTestCase_performTest + 31
20 XCTest 0x20104c48 -[XCTest run] + 82
21 XCTest 0x201033e8 -[XCTestSuite performTest:] + 139
22 XCTest 0x20104c48 -[XCTest run] + 82
23 XCTest 0x201033e8 -[XCTestSuite performTest:] + 139
24 XCTest 0x20104c48 -[XCTest run] + 82
25 XCTest 0x201033e8 -[XCTestSuite performTest:] + 139
26 XCTest 0x20104c48 -[XCTest run] + 82
27 XCTest 0x201066ba +[XCTestProbe runTests:] + 183
28 Foundation 0x03a4b5ec __NSFireDelayedPerform + 372
29 CoreFoundation 0x04054ac6 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
30 CoreFoundation 0x040544ad __CFRunLoopDoTimer + 1181
31 CoreFoundation 0x0403c538 __CFRunLoopRun + 1816
32 CoreFoundation 0x0403b9d3 CFRunLoopRunSpecific + 467
33 CoreFoundation 0x0403b7eb CFRunLoopRunInMode + 123
34 GraphicsServices 0x057495ee GSEventRunModal + 192
35 GraphicsServices 0x0574942b GSEventRun + 104
36 UIKit 0x01e7ff9b UIApplicationMain + 1225
37 Remind101 0x0008d184 main (main.m:16)
38 libdyld.dylib 0x046c5701 start + 1
NSManagedObjectContext Queue thread crashes:
Thread : Crashed: NSManagedObjectContext Queue
0 libobjc.A.dylib 0x03e250be objc_msgSend + 26
1 CoreData 0x0108ffe3 developerSubmittedBlockToNSManagedObjectContextPerform_privateasync + 83
2 libdispatch.dylib 0x044904d0 _dispatch_client_callout + 14
3 libdispatch.dylib 0x0447e047 _dispatch_queue_drain + 452
4 libdispatch.dylib 0x0447de42 _dispatch_queue_invoke + 128
5 libdispatch.dylib 0x0447ede2 _dispatch_root_queue_drain + 78
6 libdispatch.dylib 0x0447f127 _dispatch_worker_thread2 + 39
7 libsystem_pthread.dylib 0x047bfdab _pthread_wqthread + 336
8 libsystem_pthread.dylib 0x047c3cce start_wqthread + 30
There's small variations in the stack of the crashed thread, but it always includes developerSubmittedBlockToNSManagedObjectContextPerform_privateasync in the last couple of frames before a bad objc_msgSend.
My initial hypothesis was that something in my codebase was accessing MyObjectManager.managedObjectContext from off the main thread, which as I understand would be a bad time. But I put in a condition to log and pause if the accessor was called from a thread that was not the main thread, which was never hit, so there goes my low-hanging fruit on that one.
I also tried putting some logging into the entry and exit points of instances of the asynchronous NSManagedObjectContext::performBlock function in the RestKit library to see if a block was running longer than expected, holding onto a reference to the context, and dereferencing it after it had been destroyed. I would have expected a entry log without an exit log if this was the issue, but I didn't see that. I didn't try the same with performBlockAndWait because I'm assuming all synchronous operations are complete by the time my test case finished and resets the persistent store.
I'm really at a loss for even how to go about continuing my investigation into this. I realize it's not a ton to go on, but if anyone has ideas or proposals for tracking this down, I'd be happy to provide more information and try literally anything to get this resolved.
Here's what developerSubmittedBlockToNSManagedObjectContextPerform_privateasync actually does:
Gets a reference to the managed object context from within the queue
Creates it's own autorelease pool
Executes the block
Calls _processRecentChanges: on the managed object context to processing any pending user events
Drains the autorelease pool
Releases the block (the block was copied before it was passed to this method)
If the block was NULL at this point that would be a problem, but you would have different symptoms. The only things here that would use objc_msgSend are the autorelease pool and the message to _processRecentChanges:.
You can try setting a symbolic breakpoint on -[NSManagedObjectContext _processRecentChanges:] and see if that gives you any clues. It's very likely that RestKit is making some invalid assumptions about the lifetime of a managed object context and it's getting over released in your case. If that is true, it's also likely that the opposite error is being made elsewhere - that contexts are being overretained. The two problems more often than not go hand in hand. Your question doesn't include the reported reason for the crash (exception, EXC_BAD_ACCESS, etc.), so it's difficult to be definitive.
_processRecentChanges: gets called a lot, so it may still take some time to track this down. The issue would be easier to troubleshoot with the newer developer tools - you should be able to see what submitted the crashing block and from what queue, and you should be able to use Instruments with your test case. It's likely that if you can reproduce this with the newer tools that you will make progress troubleshooting it much faster.

How can I use saved tokens in NXOAuth2?

I am trying to implement a solution using the NXOauth2 pod to handle OAuth2 on my iOS app.
I am able to go through the installed application flow to get OAuth2 properties including accessToken and refreshToken - and the account is being saved into my NXOAuth2AccountStore properly (verified by inspecting [[NXOAuth2AccountStore sharedStore] accounts]).
Now that I have saved the tokens, I want to use them on subsequent app opens rather than go through requesting access again from the user. I do this here:
- (NSArray *)allAccounts
{
NXOAuth2AccountStore *store = [NXOAuth2AccountStore sharedStore];
NSArray *accounts = [store accountsWithAccountType:kIDMOAuth2AccountType];
return accounts;
}
The following call (to get some user details) works right after the user goes through the approval flow but it does not work when the app is closed and reopened.
- (void)requestOAuth2ProtectedDetails
{
[NXOAuth2Request performMethod:#"GET"
onResource:[NSURL URLWithString:#"https://www.googleapis.com/oauth2/v1/userinfo"]
usingParameters:nil
withAccount:[self allAccounts][0]
sendProgressHandler:^(unsigned long long bytesSend, unsigned long long bytesTotal) {
// e.g., update a progress indicator
}
responseHandler:^(NSURLResponse *response, NSData *responseData, NSError *error){
// Process the response
if (responseData) {
NSError *error;
NSDictionary *userInfo = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
NSLog(#"%#", userInfo);
}
if (error) {
NSLog(#"%#", error.localizedDescription);
}
}];
}
How should I use a saved accessToken / refreshToken to:
Query data using requestOAuth2ProtectedDetails?
Get an updated accessToken if required, using the refreshToken I have saved?
Here is the error I am getting:
2014-06-23 09:41:17.040 Connector[8495:60b] Got access token
2014-06-23 09:41:19.296 Connector[8495:60b] *** Assertion failure in -[NXOAuth2Client initWithClientID:clientSecret:authorizeURL:tokenURL:accessToken:tokenType:persistent:delegate:], /Users/ericgross/Documents/Connector/Pods/NXOAuth2Client/Sources/OAuth2Client/NXOAuth2Client.m:82
2014-06-23 09:41:19.300 Connector[8495:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'No token or no authorize URL'
*** First throw call stack:
(
0 CoreFoundation 0x01c281e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x019a78e5 objc_exception_throw + 44
2 CoreFoundation 0x01c28048 +[NSException raise:format:arguments:] + 136
3 Foundation 0x015874de -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
4 Connector 0x00011456 -[NXOAuth2Client initWithClientID:clientSecret:authorizeURL:tokenURL:accessToken:tokenType:persistent:delegate:] + 502
5 Connector 0x00009a59 -[NXOAuth2Account oauthClient] + 841
6 Connector 0x0001f30b -[NXOAuth2Request performRequestWithSendingProgressHandler:responseHandler:] + 667
7 Connector 0x0001e8d4 +[NXOAuth2Request performMethod:onResource:usingParameters:withAccount:sendProgressHandler:responseHandler:] + 404
8 Connector 0x00003eca -[ESGOAuth2Manager requestOAuth2ProtectedDetails] + 266
9 Connector 0x00002cba -[ESGOAuth2Manager setup] + 282
10 Connector 0x0000214f -[ESGViewController viewDidLoad] + 415
11 UIKit 0x0078633d -[UIViewController loadViewIfRequired] + 696
12 UIKit 0x007865d9 -[UIViewController view] + 35
13 UIKit 0x006a6267 -[UIWindow addRootViewControllerViewIfPossible] + 66
14 UIKit 0x006a65ef -[UIWindow _setHidden:forced:] + 312
15 UIKit 0x006a686b -[UIWindow _orderFrontWithoutMakingKey] + 49
16 UIKit 0x006b13c8 -[UIWindow makeKeyAndVisible] + 65
17 UIKit 0x00661bc0 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 2097
18 UIKit 0x00666667 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
19 UIKit 0x0067af92 -[UIApplication handleEvent:withNewEvent:] + 3517
20 UIKit 0x0067b555 -[UIApplication sendEvent:] + 85
21 UIKit 0x00668250 _UIApplicationHandleEvent + 683
22 GraphicsServices 0x02fa7f02 _PurpleEventCallback + 776
23 GraphicsServices 0x02fa7a0d PurpleEventCallback + 46
24 CoreFoundation 0x01ba3ca5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
25 CoreFoundation 0x01ba39db __CFRunLoopDoSource1 + 523
26 CoreFoundation 0x01bce68c __CFRunLoopRun + 2156
27 CoreFoundation 0x01bcd9d3 CFRunLoopRunSpecific + 467
28 CoreFoundation 0x01bcd7eb CFRunLoopRunInMode + 123
29 UIKit 0x00665d9c -[UIApplication _run] + 840
30 UIKit 0x00667f9b UIApplicationMain + 1225
31 Connector 0x0000443d main + 141
32 libdyld.dylib 0x02265701 start + 1
33 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
The first time through, this works:
- (void)performRequestWithSendingProgressHandler:(NXOAuth2ConnectionSendingProgressHandler)progressHandler
responseHandler:(NXOAuth2ConnectionResponseHandler)responseHandler;
{
NSAssert(self.me == nil, #"This object an only perform one request at the same time.");
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.resource];
[request setHTTPMethod:self.requestMethod];
self.connection = [[NXOAuth2Connection alloc] initWithRequest:request
requestParameters:self.parameters
oauthClient:self.account.oauthClient
sendingProgressHandler:progressHandler
responseHandler:responseHandler];
self.connection.delegate = self;
// Keep request object alive during the request is performing.
self.me = self;
}
And I notice the following:
(lldb) po self.account.oauthClient
<NXOAuth2Client: 0x8f1e760>
But in the failure case, this happens:
(lldb) po self.account.oauthClient
2014-06-23 10:13:25.457 Connector[8678:60b] *** Assertion failure in -[NXOAuth2Client initWithClientID:clientSecret:authorizeURL:tokenURL:accessToken:tokenType:persistent:delegate:], /Users/ericgross/Documents/Connector/Pods/NXOAuth2Client/Sources/OAuth2Client/NXOAuth2Client.m:82
error: Execution was interrupted, reason: internal ObjC exception breakpoint(-3)..
The process has been returned to the state before expression evaluation.
The library works pretty well,it automatically saves your accounts after a successful login was made. The accounts are not deleted from the account store unless you specifically say so.
For example i use this to delete all account on logout:
NXOAuth2AccountStore* store=[NXOAuth2AccountStore sharedStore];
for (NXOAuth2Account *account in [store accounts]) {
[store removeAccount:account];
}
see that you don't remove your accounts when you enter on close the app.
As for the second matter, i am searching for a solution as well

memory leak with either array or CGImageRef

I am making a program that strips out frames from a movie. This in Simulator of Xcode 5.0 on iOS 7. The number of objects I am trying to put in this array are 447. (Doesn't seem that many).
My program continuously crashes due to a memory leak either due to array size not being large enough?? (no idea if this statement is right) or due to something else. It consistently fails in the for loop only for vidoes whose number of frames are greater than 350. Less frame videos work fine.
Just a hunch could it have anything to do with the fact that I am storing large original frame images into an array? I am not scaling the frame pics down?
CODE:
NSMutableArray* allFrames = [[NSMutableArray alloc] init];
// get each frame
for (int k=0; k< totalFrames; k++)
{
int timeValue = timeValuePerFrame * k;
CMTime frameTime;
frameTime.value = timeValue;
frameTime.timescale = movie.duration.timescale;
frameTime.flags = movie.duration.flags;
frameTime.epoch = movie.duration.epoch;
CMTime gotTime;
CGImageRef myRef = [generator copyCGImageAtTime:frameTime actualTime:&gotTime error:nil];
[allFrames addObject:[UIImage imageWithCGImage:myRef]];
if (gotTime.value != frameTime.value)
NSLog (#"requested %lld got %lld for k %d", frameTime.value, gotTime.value, k);
//cleanup?
CFRelease(myRef);
}
ERROR:
2013-11-03 20:18:24.746 test[42139:a0b] requested 9925 got 9921 for k 397
2013-11-03 20:18:25.122 test[42139:a0b] requested 9950 got 9946 for k 398
everseHD(42046,0xb029b000) malloc: *** mmap(size=8298496) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
2013-11-03 20:10:31.936 ReverseHD[42046:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(
0 CoreFoundation 0x020305e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01db38b6 objc_exception_throw + 44
2 CoreFoundation 0x01fe2c3c -[__NSArrayM insertObject:atIndex:] + 844
3 CoreFoundation 0x01fe28e0 -[__NSArrayM addObject:] + 64
4 ReverseHD 0x00003131 -[v1ViewController extractImagesFromMovie] + 3089
5 libobjc.A.dylib 0x01dc5874 -[NSObject performSelector:withObject:withObject:] + 77
6 UIKit 0x00b27c8c -[UIApplication sendAction:to:from:forEvent:] + 108
7 UIKit 0x00b27c18 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
8 UIKit 0x00c1f6d9 -[UIControl sendAction:to:forEvent:] + 66
9 UIKit 0x00c1fa9c -[UIControl _sendActionsForEvents:withEvent:] + 577
10 UIKit 0x00c1e815 -[UIControl touchesBegan:withEvent:] + 254
11 UIKit 0x00b64efb -[UIWindow _sendTouchesForEvent:] + 386
12 UIKit 0x00b65d34 -[UIWindow sendEvent:] + 1232
13 UIKit 0x00b39a36 -[UIApplication sendEvent:] + 242
14 UIKit 0x00b23d9f _UIApplicationHandleEventQueue + 11421
15 CoreFoundation 0x01fb98af __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
16 CoreFoundation 0x01fb923b __CFRunLoopDoSources0 + 235
17 CoreFoundation 0x01fd630e __CFRunLoopRun + 910
18 CoreFoundation 0x01fd5b33 CFRunLoopRunSpecific + 467
19 CoreFoundation 0x01fd594b CFRunLoopRunInMode + 123
20 GraphicsServices 0x032239d7 GSEventRunModal + 192
21 GraphicsServices 0x032237fe GSEventRun + 104
22 UIKit 0x00b2694b UIApplicationMain + 1225
23 ReverseHD 0x0000244d main + 141
24 libdyld.dylib 0x02975725 start + 0
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Memory leak ⇒ lots of memory used
Lots of memory used ⇏ memory leak
You are correctly releasing myRef, which you own since it was created with a copy method, so the code you posted doesn't present any leak.
You are just using a lot of memory by trying to store 447 images.
Doesn't seem that many
is not a good evaluation. You should profile the application using Instruments with the Memory Allocation template and check for the size of the array, which is probably filling all the heap.
If you find out that the frames are too big to be stored in the array, you can reduce the size of the generated frame by using the maximumSize property of AVAssetImageGenerator, for instance
generator.maximumSize = CGSizeMake(320, 180);
As stated in the documentation:
The default value is CGSizeZero, which specifies the asset’s unscaled dimensions.

How do I fix this crash when merging core data content from context?

I have a core data project. When I do a pull to refresh on the table view, it creates a new context on a background thread, updates the database, and then merges those updates to the main context. Everything was working okay (I think), but now I'm getting the following crash:
2013-09-13 19:01:40.873 My App[2926:a0b] -[__NSCFString controllerWillChangeContent:]: unrecognized selector sent to instance 0xc26b370
2013-09-13 19:02:00.629 My App[2926:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString controllerWillChangeContent:]: unrecognized selector sent to instance 0xc26b370'
*** First throw call stack:
(
0 CoreFoundation 0x027795e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01e888b6 objc_exception_throw + 44
2 CoreFoundation 0x02816903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x0276990b ___forwarding___ + 1019
4 CoreFoundation 0x027694ee _CF_forwarding_prep_0 + 14
5 CoreData 0x002217b0 -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] + 2080
6 Foundation 0x015dbe39 __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke + 40
7 CoreFoundation 0x027d5524 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
8 CoreFoundation 0x0272d07b _CFXNotificationPost + 2859
9 Foundation 0x01515b91 -[NSNotificationCenter postNotificationName:object:userInfo:] + 98
10 CoreData 0x001264a3 -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 83
11 CoreData 0x0013be96 -[NSManagedObjectContext _mergeChangesFromDidSaveDictionary:usingObjectIDs:] + 3734
12 CoreData 0x0013afed -[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:] + 429
13 My App 0x0000bc45 -[MAManager updateMainContext:] + 245
14 libobjc.A.dylib 0x01e9a81f -[NSObject performSelector:withObject:] + 70
15 Foundation 0x0155dc18 __NSThreadPerformPerform + 285
16 CoreFoundation 0x027028af __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
17 CoreFoundation 0x0270223b __CFRunLoopDoSources0 + 235
18 CoreFoundation 0x0271f30e __CFRunLoopRun + 910
19 CoreFoundation 0x0271eb33 CFRunLoopRunSpecific + 467
20 CoreFoundation 0x0271e94b CFRunLoopRunInMode + 123
21 GraphicsServices 0x0348e9d7 GSEventRunModal + 192
22 GraphicsServices 0x0348e7fe GSEventRun + 104
23 UIKit 0x0067b94b UIApplicationMain + 1225
24 My App 0x00003442 main + 146
25 libdyld.dylib 0x0236d725 start + 0
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Here is the relevant bit of code that it's breaking on:
// merge changes to main context,fetchedRequestController will automatically monitor the changes and update tableview.
- (void)updateMainContext:(NSNotification *)notification {
assert([NSThread isMainThread]);
NSLog(#"Merging changes from context.");
[[self managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
[self save]; // update fetched results controllers
}
// this is called via observing "NSManagedObjectContextDidSaveNotification" from the background thread data load
- (void)mergeChangesFromContextDidSaveNotification:(NSNotification *)notification {
NSLog(#"Context saved!");
if (notification.object != [self managedObjectContext]) {
NSLog(#"Background context propagating to main context.");
[self performSelectorOnMainThread:#selector(updateMainContext:) withObject:notification waitUntilDone:NO];
}
}
Does anyone know why I'm getting this error and how to fix it?
Some object that is registered for a notification looks to have been released and its address re-used to store a string instead of what's expected.
Turn on zombies for your scheme, run it again, and figure out which object is being sent the notification. Then make sure you're keeping the object alive while you need it.
Your crash is an unrecognized selector with the method [__NSCFString controllerWillChangeContent:]. This method is called on the delegate of a FRC, yet somehow you have the call back performed on an NSString, which doesn't implement that method. Can you post the code where you set up your NSFetchedResultsController in that viewController?
It seems it was a problem with multiple save requests coming in concurrently (from different managed object contexts, but different threads nonetheless). The solution was to wrap the save operations in a #synchronized block to ensure that the save operations were atomic and did not happen concurrently:
- (void) save {
// lock and wait if another save operation is in progress
#synchronized([self class]) {
NSError *error;
if (![self save:&error]) {
NSLog(#"Whoops, couldn't save: %#", error);
}
}
}

ios could not locate NSManagedObjectModel , NSInternalConsistencyException

I know similar questions have been asked but they all have different answers and none seem to help me.
So, I've got an app called TherapistScheduler, which has therapistScheduler.xcdatamodel in a /Data folder at the root of the project. Inside that folder is a Session.h and Session.m file, which match up with my Session entity in my data model.
My app delegate has the functions managedObjectContext, managedObjectModel, and persistantStoreCoodinator in it.
Inside my applicationDidFinishLaunching method, I've added a view controller (loginViewController) over the top of my rootViewController (which is a tabBarController), and I'm trying to access my Session entity from there.
I'm using the following code to try and save a value - this is throwing the error:
// create session
Session *session = (Session *) [NSEntityDescription insertNewObjectForEntityForName:#"Session" inManagedObjectContext:self.managedObjectContext];
[session setSessionHash:strUserhash];
The loginViewController.h file contains:
NSManagedObjectContext *managedObjectContext; // in the interface declaration
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; // after the interface
The loginViewController.m file contains
#synthesize managedObjectContext;
Do I need to do something in the loginViewController viewDidLoad to initialise the managedObjectContext? I'm a bit lost as to how this all works. I want to be able to access the data stored in the managedObjectContext from any view I switch to on the tab bar.
I know I'll probably need to add more code to the question, but I don't know what else is needed.
The error I'm getting is this:
TherapistScheduler[40752:207] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Session''
*** Call stack at first throw:
(
0 CoreFoundation 0x02581919 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0295b5de objc_exception_throw + 47
2 CoreData 0x0004525b +[NSEntityDescription entityForName:inManagedObjectContext:] + 187
3 CoreData 0x0007cd8b +[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:] + 59
4 TherapistScheduler 0x000030ce -[LoginViewController processLoginForUserhash:andType:] + 142
5 TherapistScheduler 0x000039fa -[LoginViewController connectionDidFinishLoading:] + 330
6 Foundation 0x01f91666 -[NSURLConnection(NSURLConnectionReallyInternal) sendDidFinishLoading] + 108
7 Foundation 0x01f915bf _NSURLConnectionDidFinishLoading + 133
8 CFNetwork 0x02b8d9f1 _ZN19URLConnectionClient23_clientDidFinishLoadingEPNS_26ClientConnectionEventQueueE + 285
9 CFNetwork 0x02c56c72 _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 402
10 CFNetwork 0x02c570ea _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 1546
11 CFNetwork 0x02c570ea _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 1546
12 CFNetwork 0x02b82dfe _ZN19URLConnectionClient13processEventsEv + 100
13 CFNetwork 0x02b82c95 _ZN17MultiplexerSource7performEv + 247
14 CoreFoundation 0x02562d7f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
15 CoreFoundation 0x024c11dd __CFRunLoopDoSources0 + 333
16 CoreFoundation 0x024c07c6 __CFRunLoopRun + 470
17 CoreFoundation 0x024c0280 CFRunLoopRunSpecific + 208
18 CoreFoundation 0x024c01a1 CFRunLoopRunInMode + 97
19 GraphicsServices 0x02de62c8 GSEventRunModal + 217
20 GraphicsServices 0x02de638d GSEventRun + 115
21 UIKit 0x00215b58 UIApplicationMain + 1160
22 TherapistScheduler 0x00001f3d main + 125
23 TherapistScheduler 0x00001eb5 start + 53
24 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
I had to refer to the managedObjectContext as a property of the app delegate not self. So it looked like appDelegate.managedObjectContext.
When you passed the managedObjectContext, I think what you did is like this:
TimelineTableViewController * timelineTableViewController;
timelineTableViewController = [TimelineTableViewController alloc];
[timelineTableViewController initWithStyle:UITableViewStylePlain];
timelineTableViewController.managedObjectContext = self.managedObjectContext;
//...
and then in TimelineTableViewController's viewDidLoad: method, you wanted to fetch the data by managedObjectContext, huh?
I debugged this issue and found that TimelineTableViewController's viewDidLoad: will be dispatched quicker than timelineTableViewController.managedObjectContext = self.managedObjectContext; (where you passed the managedObjectContext from parent (or the AppDelegate) to child). So when you were trying to fetch the data, the managedObjectContext is nil actually. That's why you got this issue:
'+entityForName: could not locate an NSManagedObjectModel for entity name 'Session''
WORKAROUND:
What you have to do is to make sure that the managedObjectContext is not nil when you need to fetch the data:
TimelineTableViewController * timelineTableViewController;
timelineTableViewController = [TimelineTableViewController alloc];
timelineTableViewController.managedObjectContext = self.managedObjectContext;
[timelineTableViewController initWithStyle:UITableViewStylePlain];
// ...
I just solved this issue by this way (no need to use AppDelegate's managedObjectContext directly).

Resources