最简单的本地数据存储——NSUserDefaults

NSUserDefaults提供了一系列方法,可以存储一些基本数据类型或对象,具体用法有以下几个方法:

  • 初始化方法:静态单例方法,获得默认的本地存储区
  1. +(NSUserDefaults * _Nonnull) standardUserDefaults
  • 添加和修改键值
  1. -(void) setObject:(nullable id) forKey:(nonnull NSString *)
  • 除了setObject:forKey:方法之外还有setBool、setURL、setfloat等方法,用于添加对应的键值。传入的字符串作为键名,以便于区分和在读取的时候使用。
  • 读取键值
  1. -(id _Nullable) objectForKey:(nonnull NSString *)
  • 其中参数就是在调用setObject:forKey:时候所传入键名,同样地也有boolForKey等对用类型的方法。返回值就是之前存入的值。
  • 在存储对象时的注意事项:在存储对象时,如果不是NSData、NSArray、NSMutableArray、NSURL这样的类型,要注意必须先转化为NSData才能存储:
  1. +(NSData * _Nonnull)archivedDataWithRootObject:(nonnull id)
  • 这个方法是NSKeyedArchiver的一个静态方法,通过这个方法可以将任意遵循NSCoding协议的对象转化为NSData。然后再将NSData存入NSUserDefault即可。
  • 读取的时候直接读取到的也是NSData数据,需要转化为原来的数据
  1. +(id _Nullable)unarchiveObjectWithData:(nonnull NSData *)

这个方法是NSKeyedUnarchiver的静态方法,通过这个方法可以将NSData还原为原来的数据,这个方法是可失败的,返回值可能是nil。

参数传递的两种方式

  • 在多视图程序中,视图之间的参数传递显得尤为重要,刚才提到了NSUserDefaults的使用,显然这样的方式可以用于数据传递。这种传递方式比较适合较多视图的参数传递,例如所有视图都需要读取夜间模式的状态,大多数视图需要读取用户是否登陆等,这样的数据用NSUserDefaults进行保持比较合适。而只在两个视图之间的参数传递,可以使用类似于函数参数传递的方式,这种方式依赖于协议和Segue跳转时候的一个方法来实现,这个方法有如下定义:
  1. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  2. // Get the new view controller using [segue destinationViewController].
  3. // Pass the selected object to the new view controller.
  4. }
  • 这个方法如此重要,以至于系统在默认创建的ViewController视图类的文件中都会提到。它是在加载一个Segue的时候调用,而且是在跳转之前调用的,根据Apple官方的说明,可以使用 [segue destinationViewController]来获得跳转后的视图控制器,获得之后,可以调用这个视图控制器的方法进行参数传递。这时候推荐将该方法定义为协议。例如有如下的用法:
  1. @protocol DataTransferDelegate <NSObject>
  2. //该协议规定了视图之间参数传递的方式
  3. @optional
  4. -(void)transferBoolValue:(BOOL)state From:(id)sender;
  5. -(void)transferString:(NSString *)str From:(id)sender;
  6. @end
  • 然后在跳转前的视图控制器类中编写以下方法:
  1. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  2. if([segue.identifier isEqualToString:@"ToLogInSegue"]) {
  3. //先对identifier进行判断
  4. LogInTestViewController *viewController=[segue destinationViewController];
  5. //获得跳转后的视图控制器
  6. [viewController transferBoolValue:([_touchidswitch isOn]) From:(self)];
  7. //调用用于传递参数的协议方法
  8. }
  9. }
  • 注意,因为这个方法被所有可加载的Segue所共用,所以在有多个Segue定义的时候,推荐先判断下标示符。
  • 最后,在跳转后的标识符中,使用协议方法来接收参数即可。