Very strange behaviour...I've used before an NSNumber category called NSNumber+Currencies. Yesterday I've changed everything including core data to NSDecimalNumber so I have now a class NSDecimalNumber+Currencies. There is really no link at all! to NSNumber+Currencies anymore. However if I delete it and try to run my app in the simulator, my app crashes with the message "unrecognized selector sent to instance ..." This instance is a NSDecimalNumber and the methods I use in this category are basically the same as before. And I really import ONLY the NSDecimalNumber+Currencies. But it makes no sense...I've deleted the app from the simulator, cleaned my project, closed Xcode, removed the old category even manually from the build phases but nothing helps..is there another trick? If I leave this old category in it it runs smoothly...
My error log. However after the 2nd run my app doesn't start at all and the error message is a different one:
2014-01-28 11:51:29.458 NetIncome[2341:70b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack:
(
0 CoreFoundation 0x01ecf5e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01abe8b6 objc_exception_throw + 44
2 CoreFoundation 0x01e839c2 -[__NSArrayI objectAtIndex:] + 210
3 CoreData 0x01899c1f -[NSFetchedResultsController objectAtIndexPath:] + 255
4 NetIncome 0x00003dee -[MainCategoriesViewController tableView:cellForRowAtIndexPath:] + 206
5 UIKit 0x003ac61f -[UITableView _createPreparedCellForGlobalRow:withIndexPath:] + 412
6 UIKit 0x003ac6f3 -[UITableView _createPreparedCellForGlobalRow:] + 69
7 UIKit 0x00390774 -[UITableView _updateVisibleCellsNow:] + 2378
8 UIKit 0x0038eb81 -[UITableView _updateVisibleCellsImmediatelyIfNecessary] + 66
9 UIKit 0x0039cb5f -[UITableView _visibleCells] + 35
10 UIKit 0x0039cbb4 -[UITableView visibleCells] + 33
11 UIKit 0x0039fcc0 -[UITableView setSeparatorStyle:] + 115
12 NetIncome 0x000037d4 -[MainCategoriesViewController styleTableView] + 100
13 NetIncome 0x0000300a -[MainCategoriesViewController viewDidLoad] + 1194
14 UIKit 0x003d1318 -[UIViewController loadViewIfRequired] + 696
15 UIKit 0x003f6b15 -[UINavigationController _layoutViewController:] + 39
16 UIKit 0x003f702b -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 235
17 UIKit 0x003f7123 -[UINavigationController _startTransition:fromViewController:toViewController:] + 78
18 UIKit 0x003f809c -[UINavigationController _startDeferredTransitionIfNeeded:] + 645
19 UIKit 0x003f8cb9 -[UINavigationController __viewWillLayoutSubviews] + 57
20 UIKit 0x00532181 -[UILayoutContainerView layoutSubviews] + 213
21 UIKit 0x00328267 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
22 libobjc.A.dylib 0x01ad081f -[NSObject performSelector:withObject:] + 70
23 QuartzCore 0x001972ea -[CALayer layoutSublayers] + 148
24 QuartzCore 0x0018b0d4 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
25 QuartzCore 0x00197235 -[CALayer layoutIfNeeded] + 160
26 UIKit 0x003e3613 -[UIViewController window:setupWithInterfaceOrientation:] + 304
27 UIKit 0x00302177 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 5212
28 UIKit 0x00300d16 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 82
29 UIKit 0x00300be8 -[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 117
30 UIKit 0x00300c70 -[UIWindow _setRotatableViewOrientation:duration:force:] + 67
31 UIKit 0x002ffd0a __57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 120
32 UIKit 0x002ffc6c -[UIWindow _updateToInterfaceOrientation:duration:force:] + 400
33 UIKit 0x003009c3 -[UIWindow setAutorotates:forceUpdateInterfaceOrientation:] + 870
34 UIKit 0x00303fb6 -[UIWindow setDelegate:] + 449
35 UIKit 0x003d5737 -[UIViewController _tryBecomeRootViewControllerInWindow:] + 180
36 UIKit 0x002f9c1c -[UIWindow addRootViewControllerViewIfPossible] + 609
37 UIKit 0x002f9d97 -[UIWindow _setHidden:forced:] + 312
38 UIKit 0x002fa02d -[UIWindow _orderFrontWithoutMakingKey] + 49
39 UIKit 0x0030489a -[UIWindow makeKeyAndVisible] + 65
40 UIKit 0x002b7cd0 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1851
41 UIKit 0x002bc3a8 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
42 UIKit 0x002d087c -[UIApplication handleEvent:withNewEvent:] + 3447
43 UIKit 0x002d0de9 -[UIApplication sendEvent:] + 85
44 UIKit 0x002be025 _UIApplicationHandleEvent + 736
45 GraphicsServices 0x035202f6 _PurpleEventCallback + 776
46 GraphicsServices 0x0351fe01 PurpleEventCallback + 46
47 CoreFoundation 0x01e4ad65 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
48 CoreFoundation 0x01e4aa9b __CFRunLoopDoSource1 + 523
49 CoreFoundation 0x01e7577c __CFRunLoopRun + 2156
50 CoreFoundation 0x01e74ac3 CFRunLoopRunSpecific + 467
51 CoreFoundation 0x01e748db CFRunLoopRunInMode + 123
52 UIKit 0x002bbadd -[UIApplication _run] + 840
53 UIKit 0x002bdd3b UIApplicationMain + 1225
54 NetIncome 0x000027ad main + 141
55 libdyld.dylib 0x031c070d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
EDIT2: And this is the original error message, only shown once and immediately after deleting the relevant files:
2014-01-28 12:00:15.598 NetIncome[2872:70b] -[__NSCFNumber getLocalizedCurrencyString]: unrecognized selector sent to instance 0x8c59720
2014-01-28 12:00:15.602 NetIncome[2872:70b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber getLocalizedCurrencyString]: unrecognized selector sent to instance 0x8c59720'
*** First throw call stack:
(
0 CoreFoundation 0x01ecf5e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01abe8b6 objc_exception_throw + 44
2 CoreFoundation 0x01f6c903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x01ebf90b ___forwarding___ + 1019
4 CoreFoundation 0x01ebf4ee _CF_forwarding_prep_0 + 14
5 NetIncome 0x000358da -[NetIncomeViewController viewDidLoad] + 954
6 UIKit 0x003d1318 -[UIViewController loadViewIfRequired] + 696
7 UIKit 0x003f6b15 -[UINavigationController _layoutViewController:] + 39
8 UIKit 0x003f702b -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 235
9 UIKit 0x003f7123 -[UINavigationController _startTransition:fromViewController:toViewController:] + 78
10 UIKit 0x003f809c -[UINavigationController _startDeferredTransitionIfNeeded:] + 645
11 UIKit 0x003f8cb9 -[UINavigationController __viewWillLayoutSubviews] + 57
12 UIKit 0x00532181 -[UILayoutContainerView layoutSubviews] + 213
13 UIKit 0x00328267 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
14 libobjc.A.dylib 0x01ad081f -[NSObject performSelector:withObject:] + 70
15 QuartzCore 0x001972ea -[CALayer layoutSublayers] + 148
16 QuartzCore 0x0018b0d4 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
17 QuartzCore 0x0018af40 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
18 QuartzCore 0x000f2ae6 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
19 QuartzCore 0x000f3e71 _ZN2CA11Transaction6commitEv + 393
20 QuartzCore 0x001b0430 +[CATransaction flush] + 52
21 UIKit 0x002d9dc9 _afterCACommitHandler + 131
22 CoreFoundation 0x01e974ce __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
23 CoreFoundation 0x01e9741f __CFRunLoopDoObservers + 399
24 CoreFoundation 0x01e75344 __CFRunLoopRun + 1076
25 CoreFoundation 0x01e74ac3 CFRunLoopRunSpecific + 467
26 CoreFoundation 0x01e748db CFRunLoopRunInMode + 123
27 GraphicsServices 0x0351e9e2 GSEventRunModal + 192
28 GraphicsServices 0x0351e809 GSEventRun + 104
29 UIKit 0x002bdd3b UIApplicationMain + 1225
30 NetIncome 0x00002b3d main + 141
31 libdyld.dylib 0x031c070d start + 1
32 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
The lines of code my app crashes the first time (the last line is the one):
//Get or set and get the gross income
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDecimalNumber *grossIncome = [defaults objectForKey:@"grossincome"];
if (!grossIncome) {
[defaults setObject:[NSDecimalNumber zero] forKey:@"grossincome"];
[defaults synchronize];
grossIncome = (NSDecimalNumber *)[defaults objectForKey:@"grossincome"];
}
self.incomeValueTextField.enabled = NO;
self.incomeValueTextField.delegate = self;
self.incomeValueTextField.keyboardType = UIKeyboardTypeDecimalPad;
self.incomeValueTextField.text = [grossIncome getLocalizedCurrencyString];
And my complete category:
#import "NSDecimalNumber+Currency.h"
#import "Singletons.h"
@implementation NSDecimalNumber (Currency)
- (NSString *) getLocalizedCurrencyString
{
NSNumberFormatter *numberFormatter = [[Singletons sharedManager] numberFormatter];
NSString *numberString = [numberFormatter stringFromNumber:self];
return numberString;
}
- (NSString *) getLocalizedCurrencyStringWithDigits:(int)digits
{
if(digits == 2){
return [self getLocalizedCurrencyString];
}
NSNumberFormatter *numberFormatter;
if (digits == 0){
numberFormatter =[[Singletons sharedManager] numberFormatterNoDigits];
} else {
numberFormatter =[[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[numberFormatter setLocale:[NSLocale currentLocale]];
[numberFormatter setMinimumFractionDigits:digits];
[numberFormatter setMaximumFractionDigits:digits];
}
NSString *numberString = [numberFormatter stringFromNumber:self];
return numberString;
}
+ (NSDecimalNumber *) getUnLocalizedDecimalNumberWithString:(NSString *)currencyString
{
NSNumberFormatter *numberFormatter = [[Singletons sharedManager] numberFormatter];
NSNumber *formatedCurrency = [numberFormatter numberFromString:currencyString];
BOOL isDecimal = formatedCurrency != nil;
if(isDecimal){
return [NSDecimalNumber decimalNumberWithDecimal:[formatedCurrency decimalValue]];
} else {
return [NSDecimalNumber zero];
}
}
- (NSDecimalNumber *)abs {
if ([self compare:[NSDecimalNumber zero]] == NSOrderedAscending) {
// Number is negative. Multiply by -1
NSDecimalNumber * negativeOne = [NSDecimalNumber decimalNumberWithMantissa:1
exponent:0
isNegative:YES];
return [self decimalNumberByMultiplyingBy:negativeOne];
} else {
return self;
}
}