When my app is loading i perform some operations on the NSUserDedaults dictionary.
For some of the users, the app crashes in the following logic:
NSUserDefaults* prefs = [NSUserDefaults standartUserDefaults];
NSString* nsKey = [NSString stringWithUTF8String:ket.c_str()];
[prefs removeObjectForKey:nsKey];
[prefs synchronize];
the crash happens in the last line (synchronize).
I can't figure out why and it does not happen for me.
Any ideas?
EDIT::
This is the crash:
0 CoreFoundation 0x34d02e58 CFRetain + 20
1 CoreFoundation 0x34d0a9bf _CFArrayReplaceValues + 235
2 CoreFoundation 0x34d0f0e5 CFArrayAppendValue + 125
3 CoreFoundation 0x34d26d57 _flattenPlist + 139
4 CoreFoundation 0x34d26dbd _flattenPlist + 241
5 CoreFoundation 0x34d6e08f __CFBinaryPlistWrite + 127
6 CoreFoundation 0x34d26cad CFPropertyListWrite + 429
7 CoreFoundation 0x34d26aa5 CFPropertyListWriteToStream + 221
8 CoreFoundation 0x34d25fc1 _CFXPreferencesWritePlist + 273
9 CoreFoundation 0x34d25ead -[CFXPreferencesPropertyListSourceSynchronizer writePlistToDisk] + 129
10 CoreFoundation 0x34d22699 -[CFXPreferencesPropertyListSourceSynchronizer synchronizeAlreadyFlocked] + 601
11 CoreFoundation 0x34d2243d -[CFXPreferencesPropertyListSourceSynchronizer synchronize] + 21
12 CoreFoundation 0x34d31b3b -[CFXPreferencesPropertyListSource synchronize] + 111
13 CoreFoundation 0x34d32b93 -[CFXPreferencesSearchListSource synchronize] + 75
14 CoreFoundation 0x3719d87f CFArrayRemoveAllValues + 122
15 CoreFoundation 0x3719e1f1 CFRunLoopTimerIsValid + 36
16 libdispatch.dylib 0x3435c7e7 __func__.16042 + 2384
17 libdispatch.dylib 0x3435c647 __func__.16042 + 1968
18 libdispatch.dylib 0x3435c267 __func__.16042 + 976
19 libdispatch.dylib 0x3435c911 __func__.16042 + 2682
20 CoreFoundation 0x34d39c67 CFPreferencesAppSynchronize + 335
21 Foundation 0x32c4c8ef -[ABMultiCellContentView_Address tagForPropertyKey:] + 30
just have a try like this :
NSString* nsKey = [NSString stringWithUTF8String:ket.c_str()];
if([[NSUserDefaults standardUserDefaults] stringForKey:nsKey] != nil)
{
[[NSUserDefaults standartUserDefaults] removeObjectForKey:nsKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Related
I am experiencing a random crash in the following method:
- (void) addLineToVCard:(NSMutableString **)vCard forKey:(NSString *)key setValue:(NSString *)value
{
[*vCard appendString:[NSString stringWithFormat:#"%#:%#\r\n", key, value]];
}
and I'm calling this as:
NSMutableString* vCard = [NSMutableString string];
[self addLineToVCard:&vCard forKey:#"BEGIN" setValue:#"VCARD"];
[self addLineToVCard:&vCard forKey:#"VERSION" setValue:#"3.0"];
What am I doing wrong ? I could avoid this by passing a reference instead of a pointer object. But I would like to know the reason of crash here.
The crash log:
Crashed: com.apple.main-thread
0 libsystem_kernel.dylib 0x251e6c5c __pthread_kill + 8
1 libsystem_pthread.dylib 0x25290733 pthread_kill + 62
2 libsystem_c.dylib 0x2517b0ad abort + 108
3 libsystem_malloc.dylib 0x252180ad free_list_checksum_botch + 362
4 libsystem_malloc.dylib 0x252181db free_tiny_botch + 66
5 CoreFoundation 0x255332d3 __CFStringChangeSizeMultiple + 1838
6 CoreFoundation 0x2553178b __CFStringCheckAndReplace + 554
7 CoreFoundation 0x25491557 -[__NSCFString appendString:] + 26
8 iPhoneHandheldACT 0x1ae7cf -[ContactDetailViewController addLineToVCard:forKey:setValue:] (ContactDetailViewController.m:3009)
9 iPhoneHandheldACT 0x1ae515 -[ContactDetailViewController assembleVCard:] (ContactDetailViewController.m:2987)
10 iPhoneHandheldACT 0x1adcbd -[ContactDetailViewController shareVCard:] (ContactDetailViewController.m:2927)
11 iPhoneHandheldACT 0x1ad351 __47-[ContactDetailViewController btnSharePressed:]_block_invoke (ContactDetailViewController.m:2813)
12 UIKit 0x29f2cbd9 -[UIAlertController _fireOffActionOnTargetIfValidForAction:] + 68
13 UIKit 0x29f2d283 __85-[UIAlertController _dismissAnimated:triggeringAction:triggeredByPopoverDimmingView:]_block_invoke + 30
14 UIKit 0x29e237e3 -[UIPresentationController transitionDidFinish:] + 1230
15 UIKit 0x29e26a85 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke_2 + 192
16 UIKit 0x29c04157 -[_UIViewControllerTransitionContext completeTransition:] + 90
17 UIKit 0x29b11ba5 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 540
18 UIKit 0x29b11685 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 204
19 UIKit 0x29b1157f -[UIViewAnimationState animationDidStop:finished:] + 78
20 QuartzCore 0x27b71689 CA::Layer::run_animation_callbacks(void*) + 252
21 libdispatch.dylib 0x250c980f _dispatch_client_callout + 22
22 libdispatch.dylib 0x250d7ba9 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1524
23 CoreFoundation 0x2551db6d __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
24 CoreFoundation 0x2551c067 __CFRunLoopRun + 1574
25 CoreFoundation 0x2546b229 CFRunLoopRunSpecific + 520
26 CoreFoundation 0x2546b015 CFRunLoopRunInMode + 108
27 GraphicsServices 0x26a5bac9 GSEventRunModal + 160
28 UIKit 0x29b3f189 UIApplicationMain + 144
29 iPhoneHandheldACT 0xcbe21 main (main.m:16)
30 libdispatch.dylib 0x25113873 (Missing)
The pointer's pointer is not necessary, just like this:
- (void)addLineToVCard:(NSMutableString *)vCard forKey:(NSString *)key setValue:(NSString *)value
{
[vCard appendFormat:#"%#:%#\r\n", key, value];
}
Then use it:
NSMutableString* vCard = [NSMutableString string];
[self addLineToVCard:vCard forKey:#"BEGIN" setValue:#"VCARD"];
[self addLineToVCard:vCard forKey:#"VERSION" setValue:#"3.0"];
The result:
(lldb) po vCard
BEGIN:VCARD
VERSION:3.0
Here is my first attempt to solve crash issue in iOS app. Sharing some crash logs here.
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0x97ad6beb8
Crashed Thread: 11
Application Specific Information:
objc_msgSend() selector name: length
and here is my 11th thread.
Thread 11 Crashed:
0 libobjc.A.dylib 0x0000000180558150 objc_msgSend + 16
1 Foundation 0x00000001824f3f60 -[NSString compare:] + 28
2 Foundation 0x00000001824d88e0 _NSCompareObject + 60
3 CoreFoundation 0x0000000181a99bd0 __CFSimpleMergeSort + 88
4 CoreFoundation 0x0000000181a99c60 __CFSimpleMergeSort + 232
5 CoreFoundation 0x0000000181a99c60 __CFSimpleMergeSort + 232
6 CoreFoundation 0x0000000181a99c60 __CFSimpleMergeSort + 232
7 CoreFoundation 0x0000000181a99c60 __CFSimpleMergeSort + 232
8 CoreFoundation 0x0000000181a99c60 __CFSimpleMergeSort + 232
9 CoreFoundation 0x0000000181a99c60 __CFSimpleMergeSort + 232
10 CoreFoundation 0x0000000181a99c60 __CFSimpleMergeSort + 232
11 CoreFoundation 0x0000000181a99c60 __CFSimpleMergeSort + 232
12 CoreFoundation 0x0000000181a99c60 __CFSimpleMergeSort + 232
13 CoreFoundation 0x0000000181a99c60 __CFSimpleMergeSort + 232
14 CoreFoundation 0x0000000181a99c60 __CFSimpleMergeSort + 232
15 CoreFoundation 0x00000001819c585c CFSortIndexes + 460
16 CoreFoundation 0x00000001819c6f9c CFMergeSortArray + 372
17 Foundation 0x00000001824d80e8 _sortedObjectsUsingDescriptors + 568
18 Foundation 0x00000001825c64e0 -[NSSet(NSKeyValueSorting) sortedArrayUsingDescriptors:] + 536
19 Eikon 0x0000000100198b98 __51-[EIKNewsHeadlineStoreManager saveHeadlines:block:]_block_invoke (EIKNewsHeadlineStoreManager.m:67)
20 CoreData 0x0000000183e5e214 developerSubmittedBlockToNSManagedObjectContextPerform + 148
21 libdispatch.dylib 0x000000018099a9a0 _dispatch_client_callout + 12
22 libdispatch.dylib 0x00000001809a8ad4 _dispatch_queue_serial_drain + 924
23 libdispatch.dylib 0x000000018099e2cc _dispatch_queue_invoke + 880
24 libdispatch.dylib 0x00000001809a8fa8 _dispatch_queue_override_invoke + 340
25 libdispatch.dylib 0x00000001809aaa50 _dispatch_root_queue_drain + 536
26 libdispatch.dylib 0x00000001809aa7d0 _dispatch_worker_thread3 + 120
27 libsystem_pthread.dylib 0x0000000180ba31d0 _pthread_wqthread + 1092
28 libsystem_pthread.dylib 0x0000000180ba2d7c start_wqthread + 0
What i am trying to do is get some news headlines from server every 5 or 10 secs, sort them in some order using NSSortDescriptors and then store them in my CoreData. And that is what exactly saveHeadlines:block method is doing inside my class.
What exactly objc_msgSend() selector name: length
mean here? Any help is appreciated.
Note: Its a sporadic issue. When i test in simulator or my devices its not crashing. But some users of our app are reporting this crash.
Edited question: inside saveHeadlines:block method
__weak typeof(self) weakSelf = self;
[self.privateMOC performBlock:^{
NSMutableArray *newsTopics = [[EIKNewsTopicStoreManager managedObjectsInManagedObjectContext:self.privateMOC] mutableCopy];
[newsTopics addObjectsFromArray:[EIKNewsTopicStoreManager topicsManagedObjectForNewsFeedInContext:self.privateMOC]];
weakSelf.storedHeadlines = [NSMutableSet set];
for (NSManagedObject *storedTopic in newsTopics) {
[weakSelf.storedHeadlines addObjectsFromArray:[[storedTopic valueForKey:EIKFeedTopicRelationshipItems] allObjects]];
}
NSArray *sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:EIKNewsHeadlineAttributeHeadlineId ascending:YES]];
NSArray *orderedItems = [items sortedArrayUsingDescriptors:sortDescriptors];
NSArray *orderedHeadlines = [weakSelf.storedHeadlines sortedArrayUsingDescriptors:sortDescriptors];
And the crash is happening on the last line. i.e
NSArray *orderedHeadlines = [weakSelf.storedHeadlines sortedArrayUsingDescriptors:sortDescriptors];
Not able to figure out why.!
My NSManagedObjectContext is initialised like this[i.e privateMOC as shown in above code]
NSManagedObjectContext *confinementContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
Not much info here, but it looks to me that NSManagedObjectContext isn't valid on the thread you are performing your operation.
Please make sure that you perform all operations on the context's private queue. You can do this for example by using performBlock: or performBlockAndWait:.
Also you can't reuse instances of NSManagedObject on different threads than the one you fetched them on.
Hope that helps.
I have following function:
-(int) getCounter:(BOOL)isIncrease {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSNumber *counter = [userDefaults valueForKey:kCounter];
int intCounter;
if (counter == nil){
intCounter = 0;
} else {
intCounter = [counter intValue];
}
if (isIncrease ){
intCounter++;
[userDefaults setObject:[NSNumber numberWithInt:intCounter] forKey:kCounter];
[userDefaults synchronize];
}
return intCounter;
}
It looks simple and clear.
However sometimes I get following Exception in Fabric:
#11. Crashed: com.my.app
0 libobjc.A.dylib 0x1866def70 objc_msgSend + 16
1 CoreFoundation 0x187c1190c -[CFPrefsPlistSource synchronize] + 96
2 CoreFoundation 0x187c36674 -[CFPrefsSearchListSource alreadylocked_requestNewData] + 88
3 CoreFoundation 0x187cd80e8 __58-[_CFXPreferences appSynchronizeWithIdentifier:container:]_block_invoke + 36
4 CoreFoundation 0x187c38ea4 __108-[_CFXPreferences(SearchListAdditions) withSearchListForIdentifier:container:cloudConfigurationURL:perform:]_block_invoke + 268
5 CoreFoundation 0x187c3876c normalizeQuintuplet + 360
6 CoreFoundation 0x187c38d8c -[_CFXPreferences(SearchListAdditions) withSearchListForIdentifier:container:cloudConfigurationURL:perform:] + 104
7 CoreFoundation 0x187cd8058 -[_CFXPreferences appSynchronizeWithIdentifier:container:] + 292
8 Foundation 0x1886def90 -[NSUserDefaults(NSUserDefaults) synchronize] + 52
9 appApp 0x1004b11a4 -[MyProg getCounter:] + 4300083620
10 appApp 0x1004adb8c -[MyProg callServerWithEventName:value:withDictionary:isEvent:isNewAPI:] + 4300069772
11 appApp 0x1004ab658 __42-[MyProg sendEvent:withValues:]_block_invoke + 4300060248
12 libdispatch.dylib 0x186b1e1bc _dispatch_client_callout + 16
13 libdispatch.dylib 0x186b2af94 _dispatch_continuation_pop + 576
14 libdispatch.dylib 0x186b37634 _dispatch_source_latch_and_call + 204
15 libdispatch.dylib 0x186b20160 _dispatch_source_invoke + 820
16 libdispatch.dylib 0x186b2c210 _dispatch_queue_serial_drain + 468
17 libdispatch.dylib 0x186b219a4 _dispatch_queue_invoke + 652
18 libdispatch.dylib 0x186b2c8d8 _dispatch_queue_override_invoke + 360
19 libdispatch.dylib 0x186b2e34c _dispatch_root_queue_drain + 572
20 libdispatch.dylib 0x186b2e0ac _dispatch_worker_thread3 + 124
21 libsystem_pthread.dylib 0x186d272a0 _pthread_wqthread + 1288
22 libsystem_pthread.dylib 0x186d26d8c start_wqthread + 4
Take a look on line 9:
9 appApp 0x1004b11a4 -[MyProg getCounter:] + 4300083620
Sometimes it fails on: [NSUserDefaults(NSUserDefaults) synchronize]
and sometimes on: [NSUserDefaults(NSUserDefaults) setObject:forKey:]
Can somebody explain why I get this crash and how to avoid it?
I use UserDefaults in many places of my code but crash happen in above mentioned function.
Any suggestions?
[EDIT 1]
// in init:
mBackgroundQueue = dispatch_queue_create("com.my.app", NULL);
The root function I call getCounter:
- (void) sendEvent{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(0.1f * NSEC_PER_SEC)),
mBackgroundQueue,
^{
[self callServerWithEventName:eventName ...
withDictionary:nil
isEvent:YES
isNewAPI:YES];
}
from callServerWithEventName I call [self getCounter];
[EDIT 2]
Crash happens on setObject:forKey:]
#14. Crashed: com.my.app
0 libdispatch.dylib 0x184d397bc dispatch_group_enter + 108
1 CoreFoundation 0x185e27610 -[CFPrefsPlistSource sendFullyPreparedMessage:toConnection:settingValue:forKey:retryCount:] + 240
2 CoreFoundation 0x185e27c48 -[CFPrefsPlistSource sendMessageSettingValue:forKey:] + 388
3 CoreFoundation 0x185e26620 -[CFPrefsPlistSource alreadylocked_setValues:forKeys:count:] + 864
4 CoreFoundation 0x185ee72a8 -[CFPrefsSource setValues:forKeys:count:removeValuesForKeys:count:] + 264
5 CoreFoundation 0x185e4dafc -[CFPrefsSearchListSource alreadylocked_setValues:forKeys:count:] + 428
6 CoreFoundation 0x185ee72a8 -[CFPrefsSource setValues:forKeys:count:removeValuesForKeys:count:] + 264
7 CoreFoundation 0x185ee7444 -[CFPrefsSource setValue:forKey:] + 60
8 CoreFoundation 0x185e505c0 __108-[_CFXPreferences(SearchListAdditions) withSearchListForIdentifier:container:cloudConfigurationURL:perform:]_block_invoke + 268
9 CoreFoundation 0x185e4fe88 normalizeQuintuplet + 360
10 CoreFoundation 0x185e504a8 -[_CFXPreferences(SearchListAdditions) withSearchListForIdentifier:container:cloudConfigurationURL:perform:] + 104
11 CoreFoundation 0x185eece7c -[_CFXPreferences setValue:forKey:appIdentifier:container:configurationURL:] + 276
12 Foundation 0x1868a4eb8 -[NSUserDefaults(NSUserDefaults) setObject:forKey:] + 68
13 ifyApp 0x1004a518c -[MyProg getCounter:] + 4300362124
14 ifyApp 0x1004a1b8c -[MyProg callServerWithEventName:value:withDictionary:isEvent:isNewAPI:] + 4300348300
15 ifyApp 0x10049f658 __42-[MyProg sendEvent:withValues:]_block_invoke + 4300338776
Thanks,
The stack trace shows your crash is occurring due to a locking conflict in synchronize as you are calling it too frequently. There is no need to call synchronize and removing the call should eliminate the issue.
You can simplify your code considerably by using integerForKey & setIntegerForKey rather than objectForKey (Or valueForKey which is incorrect) and setObjectForKey.
- (NSInteger) getCounter:(BOOL)isIncrease {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger counter = [defaults integerForKey:kCounter];
if (isIncrease) {
counter++;
[defaults setIntegerForKey:kCounter];
}
return counter;
}
The problem is that you call 'getCounter' from background queue with delay and it could be nil when you try to set 'intCounter'
To me it looks like the object was released and you are calling getCounter method anyway.
That's why it show this strange 9th line.
Crashlytics reported a crash in my app, and I have no idea of what is happening.
Here is the stacktrace:
Thread : Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x30080e83 __exceptionPreprocess + 130
1 libobjc.A.dylib 0x3a3dd6c7 objc_exception_throw + 38
2 CoreData 0x2fdcf941 -[NSSQLiteStatement cachedSQLiteStatement]
3 CoreData 0x2fdcf18d -[NSSQLiteConnection prepareSQLStatement:] + 52
4 CoreData 0x2fde8edf -[NSSQLChannel selectRowsWithCachedStatement:] + 58
5 CoreData 0x2fea8e1f newFetchedRowsForFetchPlan_MT + 910
6 CoreData 0x2fde8949 -[NSSQLCore fetchRowForObjectID:] + 1180
7 CoreData 0x2fde8311 -[NSSQLCore newValuesForObjectWithID:withContext:error:] + 256
8 CoreData 0x2fde762b _PFFaultHandlerLookupRow + 398
9 CoreData 0x2fde7193 _PF_FulfillDeferredFault + 218
10 CoreData 0x2fdf6449 _PF_ManagedObject_WillChangeValueForKeyIndex + 68
11 CoreData 0x2fdf636b _sharedIMPL_setvfk_core + 110
12 CoreData 0x2fe1995d _PF_Handler_Public_SetProperty + 92
13 CoreData 0x2fe1e2a9 -[NSManagedObject setValue:forKey:] + 124
14 Application 0x0004dc45 -[DateFormatter storeValue:error:] (DateFormatter.m:65)
15 Application 0x0004ee17 -[Formatter storeValue:inObject:] (Formatter.m:176)
16 Application 0x0002b5c5 -[NSManagedObject(App) setValuesForKeysWithReceivedDictionary:] (NSManagedObject+App.m:320)
17 Application 0x0002b8f3 -[NSManagedObject(App) setValuesForKeysWithReceivedDictionary:] (NSManagedObject+App.m:377)
18 Application 0x0006352d -[ODataGetOperation processResult:] (ODataGetOperation.m:220)
19 Application 0x0004420b -[ODataOperation connectionDidFinishLoading:] (ODataOperation.m:741)
20 Foundation 0x309bb47f __65-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]_block_invoke + 54
21 Foundation 0x309bb3c1 -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] + 204
22 Foundation 0x309bb2dd -[NSURLConnectionInternal _withActiveConnectionAndDelegate:] + 60
23 CFNetwork 0x2fceaf8f ___ZN27URLConnectionClient_Classic26_delegate_didFinishLoadingEU13block_pointerFvvE_block_invoke + 74
24 CFNetwork 0x2fce9b8f ___ZN27URLConnectionClient_Classic18_withDelegateAsyncEPKcU13block_pointerFvP16_CFURLConnectionPK33CFURLConnectionClientCurrent_VMaxE_block_invoke_2 + 54
25 CFNetwork 0x2fd1b337 ___ZNK17CoreSchedulingSet13_performAsyncEPKcU13block_pointerFvvE_block_invoke + 18
26 CoreFoundation 0x2ffb3ea1 CFArrayApplyFunction + 36
27 CFNetwork 0x2fc81e05 RunloopBlockContext::perform() + 164
28 CFNetwork 0x2fc81cd5 MultiplexerSource::perform() + 220
29 CFNetwork 0x2fc81b65 MultiplexerSource::_perform(void*) + 48
30 CoreFoundation 0x3004bf1f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
31 CoreFoundation 0x3004b3e7 __CFRunLoopDoSources0 + 206
32 CoreFoundation 0x30049bd7 __CFRunLoopRun + 630
33 CoreFoundation 0x2ffb4471 CFRunLoopRunSpecific + 524
34 CoreFoundation 0x2ffb4253 CFRunLoopRunInMode + 106
35 Foundation 0x309a2697 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 254
36 Application 0x00043b4b -[ODataOperation send] (ODataOperation.m:548)
37 Application 0x0004277f -[ODataOperation operationWillStartPreparingData] (ODataOperation.m:131)
38 Foundation 0x30a5396d __NSOQSchedule_f + 60
39 libdispatch.dylib 0x3a8c64b7 _dispatch_async_redirect_invoke + 110
40 libdispatch.dylib 0x3a8c77d9 _dispatch_root_queue_drain + 224
41 libdispatch.dylib 0x3a8c79c5 _dispatch_worker_thread2 + 56
42 libsystem_pthread.dylib 0x3a9f1dff _pthread_wqthread + 298
43 libsystem_pthread.dylib 0x3a9f1cc4 start_wqthread + 8
And there is the last method that calls setValue:forKey: in an NSManagedObject subclass
- (BOOL)storeValue:(void *)theValue error:(NSError **)theError
{
NSString * value = (__bridge NSString *)theValue;
NSString * errorMessage = nil;
if (![value length] && !isOptional)
errorMessage = [NSString stringWithFormat: NSLocalizedString(#"Value cannot be nil or empty (Date) for field %#", #""), varName];
else
{
NSDate * date = nil;
if ([value length])
{
date = [NSDate dateWithISO8601: value];
if (!date)
errorMessage = [NSString stringWithFormat: NSLocalizedString(#"Invalid date %# for field %#", #""), theValue, varName];
}
if (IvarAddress)
*((__strong NSDate **) IvarAddress) = date;
else
[currentObject setValue: date forKey: varName];
}
if (errorMessage)
{
if (theError)
*theError = [NSError errorWithDomain: AppDomain code: NSFormattingError userInfo: #{ NSLocalizedDescriptionKey: errorMessage }];
#ifdef DEBUG
NSLog(#"Formatter error: %#", errorMessage);
#endif
return NO;
}
return YES;
}
I am completely open to any suggestion :)
Update : The key exists, and the value being set is an NSDate so it's an attribute of the NSManagedObject, not a relationship.
Update 2 :
I also have another crash with that method (stack trace is not exactly the same) :
Thread : Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x30080e83 __exceptionPreprocess + 130
1 libobjc.A.dylib 0x3a3dd6c7 objc_exception_throw + 38
2 CoreData 0x2fddfacb -[NSSQLCore _obtainOpenChannel] + 234
3 CoreData 0x2fea8ded newFetchedRowsForFetchPlan_MT + 860
4 CoreData 0x2fde8949 -[NSSQLCore fetchRowForObjectID:] + 1180
5 CoreData 0x2fde8311 -[NSSQLCore newValuesForObjectWithID:withContext:error:] + 256
6 CoreData 0x2fde762b _PFFaultHandlerLookupRow + 398
7 CoreData 0x2fde7193 _PF_FulfillDeferredFault + 218
8 CoreData 0x2fdf6449 _PF_ManagedObject_WillChangeValueForKeyIndex + 68
9 CoreData 0x2fdf636b _sharedIMPL_setvfk_core + 110
10 CoreData 0x2fe1995d _PF_Handler_Public_SetProperty + 92
11 CoreData 0x2fe1e2a9 -[NSManagedObject setValue:forKey:] + 124
12 Application 0x000fcc45 -[DateFormatter storeValue:error:] (DateFormatter.m:65)
13 Application 0x000fde17 -[Formatter storeValue:inObject:] (Formatter.m:176)
14 Application 0x000da5c5 -[NSManagedObject(App) setValuesForKeysWithReceivedDictionary:] (NSManagedObject+.m:320)
15 Application 0x000da8f3 -[NSManagedObject(App) setValuesForKeysWithReceivedDictionary:] (NSManagedObject+.m:377)
16 Application 0x0011252d -[ODataGetOperation processResult:] (ODataGetOperation.m:220)
17 Application 0x000f320b -[ODataOperation connectionDidFinishLoading:] (ODataOperation.m:741)
18 Foundation 0x309bb47f __65-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]_block_invoke + 54
19 Foundation 0x309bb3c1 -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] + 204
20 Foundation 0x309bb2dd -[NSURLConnectionInternal _withActiveConnectionAndDelegate:] + 60
The exception message also is different :
_obtainOpenChannel -- NSSQLCore 0x15ef3780: no database channel is available
But I think they are two related issues.
So I finally found the reasons which were all related to multithreading/concurrency issues. Basically updating the same objects on two threads at the same time..
The recently added core data debug flags (-com.apple.CoreData.ConcurrencyDebug 1) were used to figure out what was happening.
I get this exception in my Crashalytics:
0 CoreFoundation
__exceptionPreprocess + 162
1 libobjc.A.dylib
objc_exception_throw + 30
2 CoreFoundation
-[NSException initWithCoder:]
3 CoreFoundation
-[__NSCFArray objectAtIndex:] + 136
4 BusinessPlan ✭ BusinessController.m line 167
-[BusinessController tableView:didSelectRowAtIndexPath:] + 167
5 UIKit
-[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 876
6 UIKit
-[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 156
7 Foundation
__NSFireDelayedPerform + 450
8 CoreFoundation
__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14
9 CoreFoundation
__CFRunLoopDoTimer + 272
10 CoreFoundation
__CFRunLoopRun + 1232
11 CoreFoundation
CFRunLoopRunSpecific + 356
12 CoreFoundation
CFRunLoopRunInMode + 104
13 GraphicsServices
GSEventRunModal + 74
14 UIKit
UIApplicationMain + 1120
15 BusinessPlan main.m line 16
main + 16
16 BusinessPlan
start
and it is called this:
Exception Type: NSRangeException
Reason: -[__NSCFArray objectAtIndex:]: index (14) beyond bounds (14)
It only happened once so I am not sure how to reproduce it. But it happened in this code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *info = [topics_array objectAtIndex:indexPath.row];
NSString *section_name = [info objectForKey:#"section_name"];
NSString *solution_section_id = [info objectForKey:#"solution_section_id"];
// PUT THESE ITEMS INTO THE SESSION
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
[standardUserDefaults setObject:section_name forKey:#"section_name"];
[standardUserDefaults setObject:solution_section_id forKey:#"solution_section_id"];
[standardUserDefaults synchronize];
[self performSegueWithIdentifier:#"BusinessToTopic" sender:self];
}
Would anyone know how to prevent this from happening in the future and why it is happening?
EDIT:
This is the code for tableView numberOfRowsInSection
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableLabels count];
}
Thanks!