剖析Objective-C持久化教程

移动开发 iOS
本文介绍的是剖析Objective-C持久化教程,主要谈论Objective-C持久化的问题,我们来看内容。

剖析Objective-C持久化教程是本文要介绍的内容,很详细的讲解了Objective-C持久化的问题,不多说,我们来看内容。

当前需求

在做登录模块时,需要做登录的历史记录,存储本机所有登录的用户的用户名密码,以及登录策略如是否记住密码,是否自动登录等。具体实现之前,我认为这个需求看样子并不需要SQLite,因为登录用户不可能太多,而且存储的字段也就四个而已,估计用NSUserDefaults存一下数组就结了。

初遇困难

令我沮丧的是,这么一个明确的需求竟然一时半会都没有完成,用户登陆信息明明很简单的

Objective-c代码 

  1. @interface LoginUserInfo : NSObject     
  2. {     
  3.     NSString *username_;     
  4.     NSString *password_;     
  5.     BOOL     remember_;     
  6.     BOOL     autoLogin_;     
  7. }     
  8.     
  9. @property (nonatomic, copy) NSString *username;     
  10. @property (nonatomic, copy) NSString *password;     
  11. @property (nonatomic, assign) BOOL remember;     
  12. @property (nonatomic, assign) BOOL autoLogin;     
  13. @end     
  14.       
  15. @protocol LoginHistoryDelegate;    
  16.  
  17. @interface LoginUserInfo : NSObject  
  18. {  
  19.     NSString *username_;  
  20.     NSString *password_;  
  21.     BOOL     remember_;  
  22.     BOOL     autoLogin_;  
  23. }  
  24.  
  25. @property (nonatomic, copy) NSString *username;  
  26. @property (nonatomic, copy) NSString *password;  
  27. @property (nonatomic, assign) BOOL remember;  
  28. @property (nonatomic, assign) BOOL autoLogin;  
  29. @end  
  30.    
  31. @protocol LoginHistoryDelegate;   

存取的时候也很简单

Objective-c代码  

  1. // 增加一个用户要看是否是新用户,如果是新的就增加,否则要修改     
  2. - (void)addUser:(LoginUserInfo *)info     
  3. {     
  4.     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];     
  5.     NSArray *list = [self getUserList];     
  6.     NSArray *newList = nil;     
  7.     if (list == nil)     
  8.     {     
  9.         newList = [NSArray arrayWithObject:info];     
  10.     }     
  11.     else     
  12.     {     
  13.         NSMutableArray *mutList = [[NSMutableArray alloc] initWithCapacity:[list count]+1];     
  14.         [mutList addObject:info];     
  15.         for (LoginUserInfo *user in list)     
  16.         {     
  17.             if (![[info username] isEqualToString:[user username]])     
  18.             {     
  19.                 [mutList addObject:user];     
  20.             }     
  21.         }     
  22.         newList = [mutList mutableCopy];     
  23.     }     
  24.     [defaults setObject:newList forKey:kUserHistoryKey];     
  25.     [defaults synchronize];     
  26.     [newList release];     
  27. }     
  28.     
  29. - (NSArray *)getUserList     
  30. {     
  31.     NSArray *objectArray = [[NSUserDefaults standardUserDefaults]  objectForKey:kUserHistoryKey];     
  32.     return objectArray;     
  33. }    
  34.  
  35. // 增加一个用户要看是否是新用户,如果是新的就增加,否则要修改  
  36. - (void)addUser:(LoginUserInfo *)info  
  37. {  
  38.     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];  
  39.     NSArray *list = [self getUserList];  
  40.     NSArray *newList = nil;  
  41.     if (list == nil)  
  42.     {  
  43.         newList = [NSArray arrayWithObject:info];  
  44.     }  
  45.     else  
  46.     {  
  47.         NSMutableArray *mutList = [[NSMutableArray alloc] initWithCapacity:[list count]+1];  
  48.         [mutList addObject:info];  
  49.         for (LoginUserInfo *user in list)  
  50.         {  
  51.             if (![[info username] isEqualToString:[user username]])  
  52.             {  
  53.                 [mutList addObject:user];  
  54.             }  
  55.         }  
  56.         newList = [mutList mutableCopy];  
  57.     }  
  58.     [defaults setObject:newList forKey:kUserHistoryKey];  
  59.     [defaults synchronize];  
  60.     [newList release];  
  61. }  
  62.  
  63. - (NSArray *)getUserList  
  64. {  
  65.     NSArray *objectArray = [[NSUserDefaults standardUserDefaults]  objectForKey:kUserHistoryKey];  
  66.     return objectArray;  

但这样无论我怎么存储用户列表,在getUserList的时候获得的始终是nil。

各种尝试

难道是NSUserdefaults有问题么?我试了试在同个方法里改为存储普通的int,bool,甚至NSString都没问题,难道是因为没有存储数组么

Objective-c代码 

  1. NSArray *arr = [NSArray arrayWithObjects:@"xixi", @"haha", nil];     
  2.     [[NSUserDefaults standardUserDefaults] setObject:arr forKey:@"Array"];     
  3.     [[NSUserDefaults standardUserDefaults] synchronize];     
  4.      NSArray *arr2 = [[NSUserDefaults standardUserDefaults] objectForKey:@"Array"];     
  5.     NSString *s1 = [arr2 objectAtIndex:0];     
  6.     NSLog(@"%@", s1);    
  7.  
  8. NSArray *arr = [NSArray arrayWithObjects:@"xixi", @"haha", nil];  
  9.     [[NSUserDefaults standardUserDefaults] setObject:arr forKey:@"Array"];  
  10.     [[NSUserDefaults standardUserDefaults] synchronize];  
  11.      NSArray *arr2 = [[NSUserDefaults standardUserDefaults] objectForKey:@"Array"];  
  12.     NSString *s1 = [arr2 objectAtIndex:0];  
  13.     NSLog(@"%@", s1);  

但此时仍然可以很顺利的显示出s1为xixi 没办法只好上网找资料了,这时注意到我存储的是自定义的结构,而和java的序列化类似,在序列化自定义类型的时候,必须要满足可序列化的一系列条件,甚至包括序列化的规则,就Objective-C而言,必须要实现NSCoding协议

Objective-c代码 

  1. - (void)encodeWithCoder:(NSCoder *)coder;     
  2. {     
  3.     [coder encodeObject:username_ forKey:@"username"];     
  4.     [coder encodeObject:password_ forKey:@"password"];     
  5.     [coder encodeBool:remember_ forKey:@"remember"];     
  6.     [coder encodeBool:autoLogin_ forKey:@"autologin"];     
  7. }     
  8.       
  9. - (id)initWithCoder:(NSCoder *)coder;     
  10. {     
  11.     self = [[LoginUserInfo alloc] init];     
  12.     if (self != nil)     
  13.     {     
  14.         self.username = [coder decodeObjectForKey:@"username"];     
  15.         self.password = [coder decodeObjectForKey:@"password"];     
  16.         self.remember = [coder decodeBoolForKey:@"remember"];     
  17.         self.autoLogin = [coder decodeBoolForKey:@"autologin"];     
  18.     }     
  19.         
  20.     return self;     
  21. }    
  22.  
  23. - (void)encodeWithCoder:(NSCoder *)coder;  
  24. {  
  25.     [coder encodeObject:username_ forKey:@"username"];  
  26.     [coder encodeObject:password_ forKey:@"password"];  
  27.     [coder encodeBool:remember_ forKey:@"remember"];  
  28.     [coder encodeBool:autoLogin_ forKey:@"autologin"];  
  29. }  
  30.    
  31. - (id)initWithCoder:(NSCoder *)coder;  
  32. {  
  33.     self = [[LoginUserInfo alloc] init];  
  34.     if (self != nil)  
  35.     {  
  36.         self.username = [coder decodeObjectForKey:@"username"];  
  37.         self.password = [coder decodeObjectForKey:@"password"];  
  38.         self.remember = [coder decodeBoolForKey:@"remember"];  
  39.         self.autoLogin = [coder decodeBoolForKey:@"autologin"];  
  40.     }  
  41.      
  42.     return self;  
  43. }   

然后在存取的时候再加上序列化以及反序列化的代码

Objective-c代码 

  1. - (NSArray *)getUserList     
  2. {     
  3.     NSArray *objectArray = nil;     
  4.     NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:kUserHistoryKey];     
  5.     if (data != nil)     
  6.     {     
  7.         NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];     
  8.         if (oldSavedArray != nil)     
  9.             objectArray = [[NSArray alloc] initWithArray:oldSavedArray];     
  10. //        else     
  11. //            objectArray = [[NSMutableArray alloc] init];     
  12.     }     
  13.     return objectArray;     
  14. }     
  15.     
  16. // 增加一个用户要看是否是新用户,如果是新的就增加,否则要修改     
  17. - (void)addUser:(LoginUserInfo *)info     
  18. {     
  19.     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];     
  20.     NSArray *list = [self getUserList];     
  21.     NSArray *newList = nil;     
  22.     if (list == nil)     
  23.     {     
  24.         newList = [NSArray arrayWithObject:info];     
  25.     }     
  26.     else     
  27.     {     
  28.         NSMutableArray *mutList = [[NSMutableArray alloc] initWithCapacity:[list count]+1];     
  29.         [mutList addObject:info];     
  30.         for (LoginUserInfo *user in list)     
  31.         {     
  32.             if (![[info username] isEqualToString:[user username]])     
  33.             {     
  34.                 [mutList addObject:user];     
  35.             }     
  36.         }     
  37.         newList = [mutList mutableCopy];     
  38.     }     
  39.     [defaults setObject:[NSKeyedArchiver archivedDataWithRootObject:     
  40. newList] forKey:kUserHistoryKey];     
  41.     [defaults synchronize];     
  42.     [newList release];     
  43. }    
  44.  
  45. - (NSArray *)getUserList  
  46. {  
  47.     NSArray *objectArray = nil;  
  48.     NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:kUserHistoryKey];  
  49.     if (data != nil)  
  50.     {  
  51.         NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];  
  52.         if (oldSavedArray != nil)  
  53.             objectArray = [[NSArray alloc] initWithArray:oldSavedArray];  
  54. //        else  
  55. //            objectArray = [[NSMutableArray alloc] init];  
  56.     }  
  57.     return objectArray;  
  58. }  
  59.  
  60. // 增加一个用户要看是否是新用户,如果是新的就增加,否则要修改  
  61. - (void)addUser:(LoginUserInfo *)info  
  62. {  
  63.     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];  
  64.     NSArray *list = [self getUserList];  
  65.     NSArray *newList = nil;  
  66.     if (list == nil)  
  67.     {  
  68.         newList = [NSArray arrayWithObject:info];  
  69.     }  
  70.     else  
  71.     {  
  72.         NSMutableArray *mutList = [[NSMutableArray alloc] initWithCapacity:[list count]+1];  
  73.         [mutList addObject:info];  
  74.         for (LoginUserInfo *user in list)  
  75.         {  
  76.             if (![[info username] isEqualToString:[user username]])  
  77.             {  
  78.                 [mutList addObject:user];  
  79.             }  
  80.         }  
  81.         newList = [mutList mutableCopy];  
  82.     }  
  83.     [defaults setObject:[NSKeyedArchiver archivedDataWithRootObject:  
  84. newList] forKey:kUserHistoryKey];  
  85.     [defaults synchronize];  
  86.     [newList release];  

这样,总算可以持久化自定义结构了

和其他类似的语言一样,基础的序列化是个说大不大,说小不小的步骤,如果用纯c的话,就可以要完全自己去存储每个字节再读出每个字节然后解释出来,而现代语言基本上都做好了常见类型的持久化,包括更复杂的内置结构。

但即便如此,编译器也绝无可能理解用户自定义的结构,就像java里的 transient标注,还有持久化中内嵌持久化结构,持久化时的变量先后依赖关系等,持久化在网络中的传输等等等等,这也远远超过了本文的范畴 objective-c的困难支持可能要加上一个内存的释放方法不一等,确实很难便利的持久化

小结:剖析Objective-C持久化教程的内容介绍完了,希望本文对你有所帮助!

责任编辑:zhaolei 来源: 互联网
相关推荐

2011-07-21 09:42:27

Objective-C 内存 Autoreleas

2011-07-19 15:15:09

Objective-C 内存

2013-04-11 14:32:00

Objective-CiOS开发内存管理@synthesize

2013-04-11 14:37:36

Objective-CiOS内存管理系统自动创建新的aut

2011-07-18 17:14:16

Objective-C 内存 Cocoa

2011-07-08 13:49:46

Objective-C UUID

2011-08-05 14:03:39

Objective-C 对象 模板

2013-04-11 14:16:57

Objective-CiOS开发内存管理

2011-08-01 13:32:07

Objective-C Sqlite3 框架

2011-08-22 09:48:16

WindowsObjective-C

2011-08-16 10:23:04

Objective-CNSAutoreleaXcode常用键

2011-07-29 16:08:31

Objective-C 内存

2013-04-11 13:57:27

Objective-CiOS开发内存管理

2011-07-25 17:31:49

iPhone Objective-

2011-08-17 09:55:45

Objective-CCategory

2011-08-10 18:07:29

Objective-C反射

2011-08-17 10:00:12

Objective-CProperty

2011-05-11 11:20:26

Objective-C

2013-03-27 12:54:00

iOS开发Objective-C

2013-06-20 10:40:32

Objective-C实现截图
点赞
收藏

51CTO技术栈公众号