*** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value ‘<Student: 0x8399f70>’

查看官方的API,NSUserDefaults支持保存的数据类型有:NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary

对于,我们创建的NSObject不可以直接保存,如果调用setObject,会提示出错,信息如下:

*** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value ‘<Student: 0x8399f70>’ of class ‘Student’.  Note that dictionaries and arrays in property lists must also contain only property values.

当保存一个Student对象时,提示我,NSUserDefaults没有这样的属性,那么如果想要保存student中的信息,可以将studnet的信息保存到一个NSDictionary中,然后获取到这个NSDictionary,再从它里面获取每一个属性;

当然这种方式弱爆了,注意一下上面保存的类型可以保存NSData类型,不防将Student类转换为NSData类型,然后

取值时再将NSData转化为Student类;

还是用代码来说明:

Student.h 代码

   1:  #import <Foundation/Foundation.h>
   2:   
   3:  @interface Student : NSObject <NSCoding>
   4:  {
   5:      NSString *name;
   6:  }
   7:  @property (nonatomic, retain) NSString *name;
   8:   
   9:   
  10:  @end

Student.m 代码

   1:  #import "Student.h"
   2:   
   3:  @implementation Student
   4:  @synthesize name;
   5:   
   6:   
   7:  - (void)encodeWithCoder:(NSCoder *)aCoder
   8:  {
   9:      [aCoder encodeObject:self.name forKey:@"name"];
  10:  }
  11:   
  12:  - (id)initWithCoder:(NSCoder *)aDecoder
  13:  {
  14:      self = [super init];
  15:  if (self) {
  16:          self.name = [aDecoder decodeObjectForKey:@"name"];
  17:      }
  18:  return self;
  19:  }
  20:   
  21:   
  22:  - (void)dealloc
  23:  {
  24:      [name release];
  25:      name = nil;
  26:      [super dealloc];
  27:  }
  28:  @end

 

调用的代码:

   1:      Student *student = [[Student alloc] init];
   2:      [student setName:@"Jordy"];
   3:   
   4:      NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
   5:   
   6:      NSData *studentData = [NSKeyedArchiver archivedDataWithRootObject:student];
   7:      [userDefault setObject:studentData forKey:@"Student"];
   8:      [userDefault synchronize];
   9:      [student release];
  10:  
  11:  
  12:      NSData *data = [userDefault objectForKey:@"Student"];
  13:      Student *stu = [NSKeyedUnarchiver unarchiveObjectWithData:data];
  14:      NSLog(@"stu: %@, stu.name: %@",stu,stu.name);


转自:http://mario6.diandian.com/post/2013-02-28/40049432651
// // TSSUserDefaults.m // TPSecureStorage // // Created by CaiXin on 2018/4/27. // Copyright © 2018年 CaiXin. All rights reserved. // #import "TSSUserDefaults.h" #import "TSSAESCrypt.h" static TSSUserDefaults* lUserDefaults = nil; static dispatch_once_t onceToken; NSString* const TSSUserDefaultsEncryptedObjectKeyPrefix = @"[TSSUserDefaults-Encrypted]-["; NSString* const TSSUserDefaultsEncryptedObjectKeySuffix = @"]-[TSSUserDefaults-Encrypted]"; NSString* const TSSUserDefaultsUnencryptedObjectKeyPrefix = @"[TSSUserDefaults-Unencrypted]-["; NSString* const TSSUserDefaultsUnencryptedObjectKeySuffix = @"]-[TSSUserDefaults-Unencrypted]"; @interface TSSUserDefaults () @property (nonatomic, readwrite, strong) NSUserDefaults* userDefaults; @end @implementation TSSUserDefaults + (instancetype)standardUserDefaults { dispatch_once(&onceToken, ^{ lUserDefaults = [[self alloc] initWithUserDefaults:[NSUserDefaults standardUserDefaults]]; }); return lUserDefaults; } - (instancetype)initWithUserDefaults:(NSUserDefaults*)userDefaults { if (userDefaults == nil) { return nil; } self = [super init]; if (self) { self.userDefaults = userDefaults; } return self; } - (BOOL)synchronize { return [self.userDefaults synchronize]; } - (NSString*)encryptedObjectKeyForKey:(NSString*)key { return [NSString stringWithFormat:@"%@%@%@", TSSUserDefaultsEncryptedObjectKeyPrefix, key, TSSUserDefaultsEncryptedObjectKeySuffix]; } - (NSString*)unencryptedObjectKeyForKey:(NSString*)key { return [NSString stringWithFormat:@"%@%@%@", TSSUserDefaultsUnencryptedObjectKeyPrefix, key, TSSUserDefaultsUnencryptedObjectKeySuffix]; } - (id)objectForKey:(NSString *)defaultName { if (defaultName == nil) { return nil; } id obj = [self.userDefaults objectForKey:defaultName]; if (obj) { [self setObject:obj forKey:defaultName]; } else { NSData* encryptedData = [self.userDefaults objectForKey:[self encryptedObjectKeyForKey:defaultName]]; //有加密value if (encryptedData) { obj = [[TSSAESCrypt defaultCrypt] objectDecryptFromData:encryptedData]; } else { obj = [self.userDefaults objectForKey:[self unencryptedObjectKeyForKey:defaultName]]; } } return obj; } - (void)setObject:(id)value forKey:(NSString *)defaultName { [self setObject:value forKey:defaultName encrypted:YES]; } - (void)setObject:(nullable id)value forKey:(NSString *)defaultName encrypted:(BOOL)encrypted { if (defaultName == nil) { return; } NSString* newDefaultName = encrypted ? [self encryptedObjectKeyForKey:defaultName] : [self unencryptedObjectKeyForKey:defaultName]; NSString *keyToRemove = encrypted ? [self unencryptedObjectKeyForKey:defaultName] : [self encryptedObjectKeyForKey:defaultName]; [self.userDefaults removeObjectForKey:keyToRemove]; [self.userDefaults removeObjectForKey:defaultName]; if (value == nil) { [self.userDefaults removeObjectForKey:newDefaultName]; return; } if (encrypted) { NSData* encryptedData = [[TSSAESCrypt defaultCrypt] encryptWithObject:value]; if (encryptedData) { [self.userDefaults setObject:encryptedData forKey:newDefaultName]; } } else { [self.userDefaults setObject:value forKey:newDefaultName]; } } - (void)removeObjectForKey:(NSString *)defaultName { [self setObject:nil forKey:defaultName]; } @end @implementation TSSUserDefaults (Extend) - (NSInteger)integerForKey:(NSString *)defaultName { NSObject* obj = [self objectForKey:defaultName]; if ([obj isKindOfClass:[NSNumber class]]) { return ((NSNumber*)obj).integerValue; } else if ([obj isKindOfClass:[NSString class]]) { return ((NSString*)obj).integerValue; } return 0; } - (float)floatForKey:(NSString *)defaultName { NSNumber* num = [self objectForKey:defaultName]; if ([num isKindOfClass:[NSNumber class]]) { return num.floatValue; } return 0; } - (double)doubleForKey:(NSString *)defaultName { NSNumber* num = [self objectForKey:defaultName]; if ([num isKindOfClass:[NSNumber class]]) { return num.doubleValue; } return 0; } - (BOOL)boolForKey:(NSString *)defaultName { NSNumber* num = [self objectForKey:defaultName]; if ([num isKindOfClass:[NSNumber class]]) { return num.boolValue; } return 0; } - (NSString *)stringForKey:(NSString *)defaultName { NSString* str = [self objectForKey:defaultName]; if ([str isKindOfClass:[NSString class]]) { return str; } return nil; } - (NSData *)dataForKey:(NSString *)defaultName { NSData* obj = [self objectForKey:defaultName]; if ([obj isKindOfClass:[NSData class]]) { return obj; } return nil; } - (NSArray *)arrayForKey:(NSString *)defaultName { NSArray* obj = [self objectForKey:defaultName]; if ([obj isKindOfClass:[NSArray class]]) { return obj; } return nil; } - (NSDictionary *)dictionaryForKey:(NSString *)defaultName { NSDictionary* obj = [self objectForKey:defaultName]; if ([obj isKindOfClass:[NSDictionary class]]) { return obj; } return nil; } - (NSURL *)URLForKey:(NSString *)defaultName { if (defaultName == nil) { return nil; } NSURL* obj = [self.userDefaults URLForKey:defaultName]; if (obj) { [self setObject:obj forKey:defaultName]; } else { obj = [self objectForKey:defaultName]; if (![obj isKindOfClass:[NSURL class]]) { obj = nil; } } return obj; } - (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName { [self setInteger:value forKey:defaultName encrypted:YES]; } - (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName encrypted:(BOOL)encrypted { [self setObject:@(value) forKey:defaultName encrypted:encrypted]; } - (void)setFloat:(float)value forKey:(NSString *)defaultName { [self setFloat:value forKey:defaultName encrypted:YES]; } - (void)setFloat:(float)value forKey:(NSString *)defaultName encrypted:(BOOL)encrypted { [self setObject:@(value) forKey:defaultName encrypted:encrypted]; } - (void)setDouble:(double)value forKey:(NSString *)defaultName { [self setDouble:value forKey:defaultName encrypted:YES]; } - (void)setDouble:(double)value forKey:(NSString *)defaultName encrypted:(BOOL)encrypted { [self setObject:@(value) forKey:defaultName encrypted:encrypted]; } - (void)setBool:(BOOL)value forKey:(NSString *)defaultName { [self setBool:value forKey:defaultName encrypted:YES]; } - (void)setBool:(BOOL)value forKey:(NSString *)defaultName encrypted:(BOOL)encrypted { [self setObject:@(value) forKey:defaultName encrypted:encrypted]; } - (void)setURL:(NSURL *)value forKey:(NSString *)defaultName { [self setURL:value forKey:defaultName encrypted:YES]; } - (void)setURL:(NSURL *)value forKey:(NSString *)defaultName encrypted:(BOOL)encrypted { [self setObject:value.copy forKey:defaultName encrypted:encrypted]; } @end extension TSSUserDefaults { func optionalBoolForKey(_ key: String) -> Bool? { let value = self.string(forKey: key) if value == nil { return nil } else if value == optionalBoolValueOn { return true } else { return false } } func setOptionalBool(key: String, value: Bool?) { if let value = value { self.setObject(value ? optionalBoolValueOn : optionalBoolValueOff, forKey: key) } else { self.setObject(nil, forKey: key) } } } 这是userdefaults的所有代码
09-19
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值