NSUserdefaults不使用NSKeyedArchiver

时间:2015-06-10 03:09:48

标签: ios objective-c nsuserdefaults nscoding nskeyedarchiver

我有一个NSMutableArray填充了我想要保存的Movie类的对象,但它不起作用,我无法弄清楚为什么......

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

Movie.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];

返回的数组总是(null)...我不知道 我尝试了在互联网和/或stackoverflow上找到的几种不同类型的代码片段

2 个答案:

答案 0 :(得分:0)

快速测试是查看可变数组本身是否实际上不是nil。尝试输出可变数组,然后在userDefaults中设置它。

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

movies = [[NSMutableArray alloc] init];

答案 1 :(得分:0)

您的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
  5. 考虑到所有这些,您的Movie课程应如下所示:

    <强> 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
    

    <强> Movie.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 1}}。

    此外,不要不必要地使用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];