【问题标题】:NSUserdefaults not working with NSKeyedArchiverNSUserdefaults 不适用于 NSKeyedArchiver
【发布时间】:2015-06-10 03:09:48
【问题描述】:

我有一个 NSMutableArray,里面装满了我想保存的 Movie 类的对象,但它不起作用,我不知道为什么...

电影.h:

@interface Movie : NSObject <NSCoding>{
    NSString *name;
    int year;
    int length;
    NSString *file_size;
    int rating;
    NSArray *genre;
    NSString *plot;
}

@property (nonatomic, retain) NSString *name;
@property (nonatomic, assign) int year;
@property (nonatomic, assign) int length;
@property (nonatomic, retain, retain) NSString *file_size;
@property (nonatomic, assign) int rating;
@property (nonatomic, retain) NSArray *genre;
@property (nonatomic, retain) NSString *plot;

-(id) initWithName:(NSString*)newName year:(int)newYear length:(int)newLength filesize:(NSString*)newFileSize rating:(int)newRating genre:(NSArray*)newGenre plot:(NSString*)newPlot;
- (void) encodeWithCoder : (NSCoder *)encode ;
- (id) initWithCoder : (NSCoder *)decode;

@end

电影.m:

@implementation Movie

@synthesize name;
@synthesize year;
@synthesize length;
@synthesize file_size;
@synthesize rating;
@synthesize genre;
@synthesize plot;

-(id)initWithName:(NSString *)newName year:(int)newYear length:(int)newLength filesize:(NSString *)newFileSize rating:(int)newRating genre:(NSArray *)newGenre plot:(NSString *)newPlot{
    self.name = newName;
    self.year = newYear;
    self.length = newLength;
    self.file_size = newFileSize;
    self.rating = newRating;
    self.genre = newGenre;
    self.plot = newPlot;
    return self;
}
- (void)encodeWithCoder:(NSCoder *)encode;
{
    [encode encodeObject:name forKey:@"name"];
    [encode encodeInt32:year forKey:@"year"];
    [encode encodeInt32:length forKey:@"length"];
    [encode encodeObject:file_size forKey:@"file_size"];
    [encode encodeInt32:rating forKey:@"rating"];
    [encode encodeObject:genre forKey:@"genre"];
    [encode encodeObject:plot forKey:@"plot"];
}

- (id)initWithCoder:(NSCoder *)decode;
{
        NSString *name_decode = [decode decodeObjectForKey:@"name"];
        int year_decode = [decode decodeInt32ForKey:@"year"];
        int length_decode = [decode decodeInt32ForKey:@"length"];
    NSString *file_size_decode = [decode decodeObjectForKey:@"file_size"];
    int rating_decode = [decode decodeInt32ForKey:@"rating"];
    NSArray *genre_decode = [decode decodeObjectForKey:@"genre"];
    NSString *plot_decode =[decode decodeObjectForKey:@"plot"];
    return [self initWithName:name_decode year:year_decode length:length_decode filesize:file_size_decode rating:rating_decode genre:genre_decode plot:plot_decode];
}

@end

保存操作(电影是包含我的对象的 NSMutableArray):

NSUserDefaults *userDefault=[NSUserDefaults standardUserDefaults];
    NSData *encodedData = [NSKeyedArchiver archivedDataWithRootObject:Movies];
    [userDefault setObject:encodedData forKey:[NSString stringWithFormat:@"MOVIES"]];

加载动作:

NSData *decodedData = [userDefault objectForKey: [NSString stringWithFormat:@"MOVIES"]];
    NSArray *decodedArray =[NSKeyedUnarchiver unarchiveObjectWithData: decodedData];

返回的数组总是(空)...我不知道 我尝试了几种在 Internet 和/或 stackoverflow 上找到的不同类型的代码 sn-ps

【问题讨论】:

    标签: ios objective-c nsuserdefaults nscoding nskeyedarchiver


    【解决方案1】:

    您的Movie initWithName... 方法不正确。它必须是:

    - (instancetype)initWithName:(NSString *)newName year:(int)newYear length:(int)newLength filesize:(NSString *)newFileSize rating:(int)newRating genre:(NSArray *)newGenre plot:(NSString *)newPlot {
        self = [super init];
        if (self) {
            self.name = newName;
            self.year = newYear;
            self.length = newLength;
            self.file_size = newFileSize;
            self.rating = newRating;
            self.genre = newGenre;
            self.plot = newPlot;
        }
    
        return self;
    }
    

    另外,您似乎在学习一个非常过时的教程。

    1. 您无需为您的属性声明 ivars。
    2. 您不需要拨打@synthesize
    3. 您应该使用 ARC 而不是 MRC,因此您的 retain 属性应该是 strong(认为 NSString 属性应该是 copy
    4. 您的init 方法应返回instancetype,而不是id

    考虑到所有这些,您的 Movie 类应如下所示:

    电影.h

    @interface Movie : NSObject <NSCoding>
    
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, assign) int year;
    @property (nonatomic, assign) int length;
    @property (nonatomic, copy) NSString *file_size;
    @property (nonatomic, assign) int rating;
    @property (nonatomic, strong) NSArray *genre;
    @property (nonatomic, copy) NSString *plot;
    
    - (instancetype)initWithName:(NSString *)newName year:(int)newYear length:(int)newLength filesize:(NSString *)newFileSize rating:(int)newRating genre:(NSArray *)newGenre plot:(NSString *)newPlot;
    
    @end
    

    电影.m

    @implementation Movie
    
    - (instancetype)initWithName:(NSString *)newName year:(int)newYear length:(int)newLength filesize:(NSString *)newFileSize rating:(int)newRating genre:(NSArray *)newGenre plot:(NSString *)newPlot {
        self = [super init];
        if (self) {
            _name = newName;
            _year = newYear;
            _length = newLength;
            _file_size = newFileSize;
            _rating = newRating;
            _genre = newGenre;
            _plot = newPlot;
        }
    
        return self;
    }
    
    - (void)encodeWithCoder:(NSCoder *)encode;
    {
        [encode encodeObject:self.name forKey:@"name"];
        [encode encodeInt32:self.year forKey:@"year"];
        [encode encodeInt32:self.length forKey:@"length"];
        [encode encodeObject:self.file_size forKey:@"file_size"];
        [encode encodeInt32:self.rating forKey:@"rating"];
        [encode encodeObject:self.genre forKey:@"genre"];
        [encode encodeObject:self.plot forKey:@"plot"];
    }
    
    - (instancetype)initWithCoder:(NSCoder *)decode;
    {
        NSString *name_decode = [decode decodeObjectForKey:@"name"];
        int year_decode = [decode decodeInt32ForKey:@"year"];
        int length_decode = [decode decodeInt32ForKey:@"length"];
        NSString *file_size_decode = [decode decodeObjectForKey:@"file_size"];
        int rating_decode = [decode decodeInt32ForKey:@"rating"];
        NSArray *genre_decode = [decode decodeObjectForKey:@"genre"];
        NSString *plot_decode =[decode decodeObjectForKey:@"plot"];
        return [self initWithName:name_decode year:year_decode length:length_decode filesize:file_size_decode rating:rating_decode genre:genre_decode plot:plot_decode];
    }
    
    @end
    

    您没有展示如何创建和填充您的 Movies 变量(应命名为 movies,而不是 Movies。确保它不是 nil

    另外,不要不必要地使用stringWithFormat

    您的保存代码应该是:

    NSUserDefaults *userDefault=[NSUserDefaults standardUserDefaults];
    NSData *encodedData = [NSKeyedArchiver archivedDataWithRootObject:movies];
    [userDefault setObject:encodedData forKey:@"MOVIES"];
    

    你的加载代码应该是:

    NSData *decodedData = [userDefault objectForKey:@"MOVIES"];
    NSArray *decodedArray = [NSKeyedUnarchiver unarchiveObjectWithData: decodedData];
    

    【讨论】:

    • 谢谢@rmaddy!那是为我做的! :)) 顺便说一句,电影不是问题,它一定是解码/编码选择器
    【解决方案2】:

    一个快速测试是查看可变数组本身是否实际上不是 nil。在将可变数组设置为 userDefaults 之前尝试输出可变数组。

    确保可变数组在尝试向其添加对象之前已初始化。

    movies = [[NSMutableArray alloc] init];
    

    【讨论】:

      猜你喜欢
      • 2011-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-31
      • 1970-01-01
      相关资源
      最近更新 更多