数组中的多个项目会给出符合编码的错误



我有一个自定义类,我通过NSUserDefaults存储数据。当我将一个对象保存到数组中时,我可以轻松地将其读取到我的 uitableview 中。它工作得很好。但是一旦数组中有超过 1 个对象,我就会收到以下错误:

 *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSConcreteMutableData 0x7f8adad3a630> valueForUndefinedKey:]: this class is not key value coding-compliant for the key fanLocation.'

我的类的代码如下:

#import <Foundation/Foundation.h>
@interface MotileFavorite : NSObject
@property (nonatomic, strong) NSString *favoriteName;
@property (nonatomic, strong) NSString *onNotificationsScreen;
@property (nonatomic, strong) NSString *fanLocation;
-(id)initWithName:(NSString *)favoriteName
     withLocation:(NSString*)fanLocation
     withIsOnNotificationsScreen:(NSString*)onNotificationsScreen;

@end
import "MotileFavorite.h"
@implementation MotileFavorite
-(id)initWithName:(NSString *)favoriteName withLocation:(NSString *)fanLocation withIsOnNotificationsScreen:(NSString *)onNotificationsScreen
{
    self = [super init];
    self.favoriteName = favoriteName;
    self.fanLocation = fanLocation;
    self.onNotificationsScreen = onNotificationsScreen;
    return  self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
    //Encode properties, other class variables, etc
    [encoder encodeObject:self.favoriteName forKey:@"favoriteName"];
    [encoder encodeObject:self.fanLocation forKey:@"fanLocation"];
    [encoder encodeObject:self.onNotificationsScreen forKey:@"onNotificationsScreen"];
}
- (id)initWithCoder:(NSCoder *)decoder {
    if((self = [super init])) {
        //decode properties, other class vars
        self.favoriteName = [decoder decodeObjectForKey:@"favoriteName"];
        self.fanLocation = [decoder decodeObjectForKey:@"fanLocation"];
        self.onNotificationsScreen = [decoder decodeObjectForKey:@"onNotificationsScreen"];
    }
    return self;
}
@end

表视图的代码是这样的

#import <UIKit/UIKit.h>
@interface FavoritesListTableViewController : UITableViewController

@end
NSArray *favoritesArray;
NSArray *favoriteListNameArray;
NSArray *favoriteListLocationArray;

.m viewDidLoad 位于发生错误的位置下方

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.allowsMultipleSelectionDuringEditing = NO;
    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults synchronize];
    NSMutableArray *favoritesList = [defaults objectForKey:@"favoritesList"];
    NSMutableArray *unArchivedFavoritesList = [NSMutableArray arrayWithCapacity:favoritesList.count];
    for (NSData *mfavObject in favoritesList) {
        NSData *mfUnEndocedObject = [NSKeyedUnarchiver unarchiveObjectWithData:mfavObject];
        [unArchivedFavoritesList addObject:mfUnEndocedObject];
    }

    favoriteListLocationArray = [unArchivedFavoritesList valueForKey:@"fanLocation"];
    favoriteListNameArray = [unArchivedFavoritesList valueForKey:@"favoriteName"];
}

尝试读取收藏夹列表位置数组时发生错误。这是我保存到数组时的代码:

- (IBAction)savePressed:(id)sender {
    if (_NotificationsSegmentedControl.selectedSegmentIndex == 0){
        _notificationBool = @"Yes";
    }
    else{
        _notificationBool = @"No";
    }
    MotileFavorite *favorite = [[MotileFavorite alloc] initWithName:_nameFavoriteTextField.text withLocation:@"FANLOCATION" withIsOnNotificationsScreen:_notificationBool];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableArray *favoritesList = [[NSMutableArray alloc] initWithArray: [defaults objectForKey:@"favoritesList"]];
    [favoritesList addObject:favorite];  
    NSMutableArray *archiveArray = [NSMutableArray arrayWithCapacity:favoritesList.count];
    for (MotileFavorite *mfavObject in favoritesList) {
        NSData *mfEndocedObject = [NSKeyedArchiver archivedDataWithRootObject:mfavObject];
        [archiveArray addObject:mfEndocedObject];
    }

    [defaults setObject:archiveArray forKey:@"favoritesList"];
    [defaults synchronize];
}

当我将其读到视图时,我基本上尝试做保存它的"相反",但显然这不适用于多个值。知道使它适用于用户默认值中的多个值的代码是什么吗?谢谢!

错误消息非常清楚。您正在向 NSData 对象发送valueForKey:。你不能这么做。

让我们看一下您的代码,看看这是如何发生的。根据您自己的代码,您正在创建 unArchivedFavoritesList 作为 NSData 对象的 NSArray:

NSData *mfUnEndocedObject = 
    [NSKeyedUnarchiver unarchiveObjectWithData:mfavObject];
[unArchivedFavoritesList addObject:mfUnEndocedObject];

随后,您将在该阵列上调用valueForKey:

[unArchivedFavoritesList valueForKey:@"fanLocation"];

发送到 NSArray valueForKey:会将valueForKey:发送到数组的每个包含对象。但是 NSData 对象不响应valueForKey: ,所以这毫无意义 - 我们崩溃了。

编辑:发生这种情况的原因是您在将对象放入数组之前对其进行存档。这不是归档的工作方式。存档存档对象图。您使对象可存档,并将对象本身放入数组中。然后你存档阵列!整个图形 - 数组和对象 - 为您存档。现在,您有一个可逆操作。

您必须编辑MotileFavored才能使用initWithCoder函数来取消存档数据。

@implementation MotileFavorite
- (id)initWithCoder:(NSCoder *)coder;
{
    if(self = [super init])
    {
        self.favoriteName = [coder decodeObjectForKey:@"favoriteName"];
        self.fanLocation = [coder decodeObjectForKey:@"fanLocation"];
        self.onNotificationsScreen = [coder decodeObjectForKey:@"fanLocation"];
    }
    return self;
}
@end

然后执行此操作以存档和取消存档。

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
MotileFavorite *m1 = [[MotileFavorite alloc] initWithName:@"A2"
                                             withLocation:@"A"
                              withIsOnNotificationsScreen:@"A"];
MotileFavorite *m2= [[MotileFavorite alloc] initWithName:@"A1"
                                            withLocation:@"A"
                             withIsOnNotificationsScreen:@"A"];
NSArray *array = [[NSArray alloc] initWithObjects:m1,m2, nil];

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver
                                                  archivedDataWithRootObject:array]
                                          forKey:@"favoritesList"];
[defaults synchronize];
NSData *favouriteData = [defaults objectForKey:@"favoritesList"];
NSArray *unArchivedFavoritesList = [NSKeyedUnarchiver unarchiveObjectWithData:favouriteData];

favoriteListLocationArray = [unArchivedFavoritesList valueForKey:@"fanLocation"];
favoriteListNameArray = [unArchivedFavoritesList valueForKey:@"favoriteName"];

[NSKeyedArchiver archivedDataWithRootObject:]从数组生成一个 NSData 对象。将其保存在 NSUserDefaults 中。

initWithCoder执行与 encodeWithCoder 函数相反的操作,以取回对象。

[NSKeyedUnarchiver unarchiveObjectWithData:]NSData 中取回数组。

最新更新