简体   繁体   English

NSUserDefaults setObject方法导致应用程序在ios8中崩溃

[英]NSUserDefaults setObject method causes the app to crash in ios8

I am having an app in which I am passing some data between viewControllers with NSUserDefaults. 我有一个应用程序,其中我正在使用NSUserDefaults在viewController之间传递一些数据。

This is the code below I am using. 这是我正在使用的以下代码。

[[NSUserDefaults standardUserDefaults]setObject:selectedLists forKey:UserID];

Where selectedLists is NSMutableArray and UserID is NSString . 其中selectedListsNSMutableArray,而UserID是NSString

This code works fine until ios7 and xCode5. 直到ios7和xCode5,此代码才能正常工作。

Since I have updated xCode6 and now I am using ios8, my app works fine with xCode 6 and ios 7.1 but the app crashes when I run the app in ios8 devices with the error below. 由于我已经更新了xCode6,现在使用的是ios8,因此我的应用程序可以在xCode 6和ios 7.1上正常运行,但是当我在ios8设备中运行该应用程序时,该应用程序崩溃了,并出现以下错误。

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0x7a027060'

I just don't understand what is the problem here. 我只是不明白这里出了什么问题。

If anyone has faced this problem with ios8 then please help me. 如果有人遇到过ios8的此问题,请帮助我。

Thanks in advance. 提前致谢。

Value of selectedLists selectedLists的

    {
        CardFace = Word;
        ImportFlag = Import;
        ListID = 1;
        ListName = "Adjectives - Appearance";
        QuizBy = Definition;
        UserID = 1;
    }

and UserId is 1. 并且UserId为1。

EDITED 已编辑

 *** First throw call stack:
    (
        0   CoreFoundation                      0x06a24df6 __exceptionPreprocess + 182
        1   libobjc.A.dylib                     0x03ac8a97 objc_exception_throw + 44
        2   CoreFoundation                      0x06a2ca75 -[NSObject(NSObject) doesNotRecognizeSelector:] + 277
        3   CoreFoundation                      0x069759c7 ___forwarding___ + 1047
        4   CoreFoundation                      0x0697558e _CF_forwarding_prep_0 + 14
        5   CoreFoundation                      0x068df30f CFStringGetLength + 143
        6   CoreFoundation                      0x069de510 _CFPrefsEncodeKeyValuePairIntoMessage + 64
        7   CoreFoundation                      0x06a275cf -[CFPrefsPlistSource sendMessageSettingValue:forKey:] + 111
        8   CoreFoundation                      0x06954f3a -[CFPrefsPlistSource alreadylocked_setValue:forKey:] + 250
        9   CoreFoundation                      0x06954e22 -[CFPrefsSource setValue:forKey:] + 82
        10  CoreFoundation                      0x06954dc3 ___CFPreferencesSetValueWithContainer_block_invoke + 51
        11  CoreFoundation                      0x0690ef0a +[CFPrefsSource withSourceForIdentifier:user:byHost:container:perform:] + 1274
        12  CoreFoundation                      0x06954d61 _CFPreferencesSetValueWithContainer + 225
        13  CoreFoundation                      0x06a0aa62 _CFPreferencesSetAppValueWithContainer + 66
        14  Foundation                          0x0347f53f -[NSUserDefaults(NSUserDefaults) setObject:forKey:] + 59
        15  Foundation                          0x0353eeba -[NSUserDefaults(NSKeyValueCoding) setValue:forKey:] + 68
        16  Vocab                               0x000eaecc Vocab + 720588
        17  libobjc.A.dylib                     0x03ade7cd -[NSObject performSelector:withObject:withObject:] + 84
        18  UIKit                               0x022a079d -[UIApplication sendAction:to:from:forEvent:] + 99
        19  UIKit                               0x022a072f -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64
        20  UIKit                               0x023d3a16 -[UIControl sendAction:to:forEvent:] + 69
        21  UIKit                               0x023d3e33 -[UIControl _sendActionsForEvents:withEvent:] + 598
        22  UIKit                               0x023d309d -[UIControl touchesEnded:withEvent:] + 660
        23  UIKit                               0x022f0aba -[UIWindow _sendTouchesForEvent:] + 874
        24  UIKit                               0x022f1595 -[UIWindow sendEvent:] + 791
        25  UIKit                               0x022b6aa9 -[UIApplication sendEvent:] + 242
        26  UIKit                               0x022c68de _UIApplicationHandleEventFromQueueEvent + 20690
        27  UIKit                               0x0229b079 _UIApplicationHandleEventQueue + 2206
        28  CoreFoundation                      0x069487bf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
        29  CoreFoundation                      0x0693e2cd __CFRunLoopDoSources0 + 253
        30  CoreFoundation                      0x0693d828 __CFRunLoopRun + 952
        31  CoreFoundation                      0x0693d1ab CFRunLoopRunSpecific + 443
        32  CoreFoundation                      0x0693cfdb CFRunLoopRunInMode + 123
        33  GraphicsServices                    0x0436424f GSEventRunModal + 192
        34  GraphicsServices                    0x0436408c GSEventRun + 104
        35  UIKit                               0x0229ee16 UIApplicationMain + 1526
        36  Vocab                               0x0004c9bc Vocab + 72124
        37  libdyld.dylib                       0x03ee6ac9 start + 1
    )
    libc++abi.dylib: terminating with uncaught exception of type NSException

Edited On my tableview's didselect method... 在tableview的didselect方法上进行了编辑 ...

UserID = [[users objectAtIndex:indexPath.row] valueForKey:@"UserID"];

where users is an array. 用户是一个数组。

You should check the UserID type because crash is not related with changing NSArray to NSMutableArray . 您应该检查UserID类型,因为崩溃与将NSArray更改为NSMutableArray无关。

You must be confusing NSNumber with NSString on your userID: 您必须在userID上将NSNumber与NSString混淆:

Change your code and instead of userID use the variable userIDString 更改您的代码,而不使用userID使用变量userIDString

NSString userIDString;

//If UserID is class of NSNumber turn its value to NSString
if ([UserID isKindOfClass:[NSNumber class]]) 
{ 
    userIDString = [UserID stringValue]; 
} 
else 
    userIDString = UserID ;

During runtime UserId is probably of type NSNumber , even if in your code it is typed NSString . 在运行时, UserId的类型可能为NSNumber ,即使在您的代码中它的类型为NSString

Check how UserId is created. 检查如何创建UserId Use the debugger to check the runtime type. 使用调试器检查运行时类型。

The newly posted code shows that your retrieve the UserId from the users array which probably consists of dictionaries. 新发布的代码显示,您从users数组中检索了UserId ,其中可能包含字典。 In those dictionaries there's a value for the key UserID . 在那些词典中,键UserID带有一个值。 It depends on how the array of dictionaries is created (json deserialization?) but it seems that the type of object referred to by the UserID key is a number type, not a string. 这取决于字典数组的创建方式(json反序列化?),但看来UserID键所引用的对象类型是数字类型,而不是字符串。 So all you have to do is convert this number into a string: 因此,您要做的就是将此数字转换为字符串:

UserID = [[[users objectAtIndex:indexPath.row] valueForKey:@"UserID"] stringValue];

Now your key is always a string. 现在,您的密钥始终是字符串。

I think can't store NSMutableArrays in NSUserDefaults since iOS8 (according to different posts). 我认为自iOS8起,无法在NSUserDefaults存储NSMutableArrays (根据不同的帖子)。 Try casting it into an array before (or create a new one). 尝试先将其转换为数组(或创建一个新数组)。

Like this for example : 例如这样:

NSArray *arr = [NSArray arrayWithArray:selectedLists];

And store arr in NSUserDefaults . 并将arr存储在NSUserDefaults

Try to encode your data in NSData and save it in NSUserDefaults and retrieved back, once needed. 尝试将数据编码为NSData并将其保存在NSUserDefaults并在需要时取回。 Have a look at this thread and this one. 看看这个线程和这个线程。

Should not use NSUSerdefault to keep a collection of custom objects. 不应使用NSUSerdefault保留自定义对象的集合。 You should save them using NSkeyedUnarchiver/NSkeyedarchiver. 您应该使用NSkeyedUnarchiver / NSkeyedarchiver保存它们。 Ref: NSCoding. 参考:NSCoding。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM