zoukankan      html  css  js  c++  java
  • 控制器和应用数据存储

    1、UINavigationController, 继承UIViewController,UINavigationController以栈的形式保存子控制器

        1)把控制器添加到导航控制器栈里有两种方式:

           导航控制器 UINavigationController *nav = [[UINavigationController alloc] init];

           比如有一个控制器:UIViewController *control = [[UIViewController alloc] init];

           第一种方式:[nav addChildViewController:control];

           第二种方式:[nav pushViewController:control animated:YES];

        2)从导航控制器栈里中移出栈顶的控制器:- (UIViewController *)popViewControllerAnimated:(BOOL)animated;

           回到指定的子控制器:- (NSArray *)popToViewController:(UIViewController *)viewController ainimated:(BOOL)animated;

           回到根控制器:- (NSArray *)popToRootViewController ainimated:(BOOL)animated;

        3)UINavigationItem的属性:

    //左上角的返回按钮
    @property(nonatomic, retain)  UIBarButtonItem  *backBarButtonItem;
    
    //中间的标题视图
    @property(nonatomic, retain)  UIView  *titleView;
    
    //中间的标题文字
    @property(nonatomic, copy)  NSString  *title;
    
    //左上角的视图
    @property(nonatomic, retain)  UIBarButtonItem  *leftBarButtonItem;
    
    //右上角的视图
    @property(nonatomic, retain)  UIBarButtonItem  *rightButtonItem;
    View Code

    2、UIStoryboardSegue : 每个Segue有三个属性:

    //唯一标识
    @property(nonatomic, readonly)  NSString  *identifier;
    
    //来源控制器
    @property(nonatomic, readonly)  id sourceViewController;
    
    //目标控制器
    @property(nonatomic, readonly)  id destinationViewController;
    View Code

    执行segue的时候,跳转之前会调用一个方法:- (void)prepareForSegue:(UIStoryboardSegue *)segue  sender:(id)sender;

    一般可以在这个方法做一些准备操作,例如给下一个控制器传值

    3、ios应用常用的数据的存储方式主要有:

       1)、plist (利用xml属性列表归档NSDictionary、NSArray、NSData、NSNumber等系统类型数据)

       2)、NSUserDefaults 偏好设置

       3)、NSKeydeArchiver归档(一般用来存储自定义对象)

       4)、SQLite(关系型数据库,不能直接存储对象,使用sql语句序列化对象存储)

       5)、Core Data (对象型数据库,吧内部环境屏蔽)

    4、应用程序沙盒(模拟器沙盒大概路径:/Users/tan/Library/Developer/CoreSimulator/Devices/......

       每个应用程序都有自己的应用沙盒,用来和其他程序隔离;

       沙盒的文件系统目录有三个:Documents、Library(又包含Caches和Preferences)、tmp;

       1)、应用程序包包含了所有的资源文件和可执行文件;  

       2)、Documents保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录;

       3)、tmp保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时,不会备份该目录;

       4)、Library/Caches 保存应用运行时生成的非重要的需要持久化的数据,iTunes同步设备时不会备份该目录;

       5)、Library/Prefences保存应用的所有偏好设置,iTunes同步设备时会备份该目录

       测试获取应用程序沙盒下和真机下Documents路径和安装包资源文件路径方法:

       

    //沙盒Documents路径 : NSSearchPathForDirectoriesInDomains函数第三个参数布尔类型expandTilde表示是否显示全路径
        NSString *path1 = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
        NSString *path2 = [NSHomeDirectoryForUser(nil) stringByAppendingPathComponent:@"Documents"];
        NSString *path3 = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        NSString *path4 = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO) lastObject];
        NSLog(@"path1 = %@", path1);
        NSLog(@"path2 = %@", path2);
        NSLog(@"path3 = %@", path3);
        NSLog(@"path4 = %@", path4);
        
        //安装包资源文件路径
        NSString *indexUrl = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
        NSLog(@"indexUrl: %@", indexUrl);
    
    /*
         模拟器测试打印日志:
         path1 = /Users/PX/Library/Developer/CoreSimulator/Devices/57E9C8A1-2AB2-48C9-9304-254BF841DC2D/data/Containers/Data/Application/948A9B33-FEB7-479B-90FB-F27D573663DF/Documents
         path2 = /Users/PX/Library/Developer/CoreSimulator/Devices/57E9C8A1-2AB2-48C9-9304-254BF841DC2D/data/Containers/Data/Application/948A9B33-FEB7-479B-90FB-F27D573663DF/Documents
         path3 = /Users/PX/Library/Developer/CoreSimulator/Devices/57E9C8A1-2AB2-48C9-9304-254BF841DC2D/data/Containers/Data/Application/948A9B33-FEB7-479B-90FB-F27D573663DF/Documents
         path4 = ~/Documents
         indexUrl: /Users/PX/Library/Developer/CoreSimulator/Devices/57E9C8A1-2AB2-48C9-9304-254BF841DC2D/data/Containers/Bundle/Application/67C8E4C2-3DF1-4673-8FE9-48397EDA7759/tan_IOSFuXi.app/index.html
         
         真机测试打印日志:
         path1 = /var/mobile/Containers/Data/Application/CC29D2BC-F10B-41F4-A1CD-239E379604F6/Documents
         path2 = /var/mobile/Containers/Data/Application/CC29D2BC-F10B-41F4-A1CD-239E379604F6/Documents
         path3 = /var/mobile/Containers/Data/Application/CC29D2BC-F10B-41F4-A1CD-239E379604F6/Documents
         path4 = ~/Documents
         indexUrl: /var/mobile/Containers/Bundle/Application/2B0645D3-0B3F-46BF-841C-202B5A5A0C4B/tan_IOSFuXi.app/index.html
         */

     5、应用程序数据存储方式示例代码:

    //定义两个属性
    @property (weak, nonatomic) IBOutlet UITextField *txtPlist; //输入信息
    @property (weak, nonatomic) IBOutlet UILabel *lblPlist; //展示信息
    View Code

       1)、使用plist文件来存储系统类数据

    //将字典数据存入*.plist文件中
    - (IBAction)savePlist:(id)sender{
        //沙盒Documents文件夹路径 最后那个参数expandTilde代表是否展开完整路径
        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"tan.plist"];
    
        NSDictionary *dic = @{@"msg": self.txtPlist.text};
        //原子的写入文件中 
        if ([dic writeToFile:path atomically:YES]){
            self.txtPlist.text = @"保存成功";
        }
        else{
            self.txtPlist.text = @"保存失败";
        }
    }
    
    //* 读取数据plist文件数据 */
    - (IBAction)readPlist:(id)sender{
        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"tan.plist"];
        NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:path];
        self.lblPlist.text = [NSString stringWithFormat:@"%@: %@", [[dic allKeys] firstObject], [[dic allValues] lastObject]];
    }
    View Code

       

       2)、使用偏好设置存储

      
    /* 保存数据到用户偏好设置中 */
    - (IBAction)saveDataToUserPreference:(id)sender{
        NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
        // 自动帮我们生成一个plist文件存放在偏好设置的文件夹
        [ud setObject:self.txtPlist.text forKey:@"msg"];
        
        // 同步:把内存中的数据和沙盒同步
        [ud synchronize];
        self.txtPlist.text = @"存储到偏好设置OK";
    }
    
    /* 从用户偏好设置中读取数据 */
    - (IBAction)readDataByUserPreference:(id)sender{
        NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
        self.lblPlist.text = [ud objectForKey:@"msg"];
    }
    View Code

      

       

       3)、使用NSKeyedArchiver对自定义对象进行归档, 使用NSKeyedUnarchiver解析归档对象

          首先自定义类需要实现NSCoding协议,然后实现方法

         - (void)encodeWithCoder:(NSCoder *)aCoder; //定义自定义类哪些属性需要归档,如何归档

         - (id)initWithCoder:(NSCoder *)aDecoder; // 定义归档对象解析时哪些属性需要解析,如何解析

         如果父类也遵守了NSCoding协议,应该在encodeWithCoder:方法中加上一句:[super encodeWithCode:encode];

         确保继承的实例变量也能被编码,即也能被归档

         应该在initWithCoder:方法中加上一句:self = [super initWithCoder:decoder];

         确保继承的实例变量也能被解码,即也能被恢复

       
    #import <Foundation/Foundation.h>
    
    @interface TanPerson : NSObject <NSCoding>
    
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, assign) int age;
    @property (nonatomic, copy) NSString *email;
    @property (nonatomic, copy) NSString *address;
    
    + (instancetype)tanPersonWithDict:(NSDictionary *)dict;
    - (instancetype)initWithDict:(NSDictionary *)dict;
    
    @end
    View Code
       
    #import "TanPerson.h"
    
    @implementation TanPerson
    
    + (instancetype)tanPersonWithDict:(NSDictionary *)dict{
        return [[self alloc] initWithDict:dict];
    }
    
    - (instancetype)initWithDict:(NSDictionary *)dict{
        if (self = [super init]){
            [self setValuesForKeysWithDictionary:dict];
        }
        return self;
    }
    
    /**
     对象归档时调用
     哪些属性需要归档,又如何归档
     */
    - (void)encodeWithCoder:(NSCoder *)aCoder{
        [aCoder encodeObject:_address forKey:@"tan_address"];
        [aCoder encodeInt:_age forKey:@"age"];
        [aCoder encodeObject:_name forKey:@"tan_name"];
    }
    
    /**
     解析对象时调用
     哪些属性需要解析,如何解析
     */
    - (id)initWithCoder:(NSCoder *)aDecoder{
        if (self = [super init]){
            _address = [aDecoder decodeObjectForKey:@"tan_address"];
            _age = [aDecoder decodeIntForKey:@"age"];
            _name = [aDecoder decodeObjectForKey:@"tan_name"];
        }
        return self;
    }
    @end
    View Code

         //控制器内方法

    /* NSKeyedArchiver归档 用来存储自定义对象 */
    - (IBAction)saveDataToArchiver:(id)sender{
        TanPerson *person = [[TanPerson alloc] init];
        person.age = 25;
        person.address = self.txtPlist.text;
        person.name = @"呼呼";
        
        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"tanPerson.data"];
        
        if ([NSKeyedArchiver archiveRootObject:person toFile:path]){
            self.txtPlist.text = @"对象归档OK了";
        }
        else{
            self.txtPlist.text = @"对象归档行动失败!";
        }
    }
    
    /* 使用NSKeyedUnarchiver解析归档对象 */
    - (IBAction)readyDataByArchiver:(id)sender{
        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"tanPerson.data"];
        
        TanPerson *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
        self.lblPlist.text = [NSString stringWithFormat:@"name: %@, age: %d, address: %@", person.name, person.age, person.address];
    }
    View Code

        4)使用NSKeyedArchiver归档多个对象和解析

    /* 使用NSKeyedArchiver归档多个对象 */
    - (IBAction)saveMulObjectByArchive:(id)sender{
        TanPerson *person1 = [[TanPerson alloc] init];
        person1.name = @"小毛";
        TanPerson *person2 = [[TanPerson alloc] init];
        person2.name = @"小亲";
        
        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"tanMulPerson.data"];
        
        //NSData可以为一些数据提供临时存储空间,以便随后写入文件,或者存放从磁盘读取的文件内容
        NSMutableData *data = [NSMutableData data]; //新建一块可变数据区
        
        //将数据区连接到一个NSKeyedArchiver对象
        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
        //开始存档对象,存档的数据都会存储到data中
        [archiver encodeObject:person1 forKey:@"perOne"];
        [archiver encodeObject:person2 forKey:@"perTwo"];
        //存档完毕  必须调用
        [archiver finishEncoding];
        //将存档的数据存入文件
        [data writeToFile:path atomically:YES];
        
        self.txtPlist.text = @"多个对象存档完成了";
    }
    
    /* 使用NSKeyedUnArchiver解析多个归档对象 */
    - (IBAction)readMulObjectByArchiver:(id)sender{
        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"tanMulPerson.data"];
        //将数据读取到data上
        NSMutableData *data = [NSMutableData dataWithContentsOfFile:path];
        
        //解析数据
        NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
        TanPerson *person1 = [unArchiver decodeObjectForKey:@"perOne"];
        TanPerson *person2 = [unArchiver decodeObjectForKey:@"perTwo"];
        
        [unArchiver finishDecoding]; //恢复完毕 可以不调用
        
        self.lblPlist.text = [NSString stringWithFormat:@"name1: %@, name2: %@", person1.name, person2.name];
    }
    

      

  • 相关阅读:
    Django+xadmin打造在线教育平台(八)
    Django+xadmin打造在线教育平台(七)
    Django+xadmin打造在线教育平台(六)
    Django+xadmin打造在线教育平台(五)
    Django+xadmin打造在线教育平台(四)
    Django+xadmin打造在线教育平台(三)
    Django+xadmin打造在线教育平台(二)
    Django+xadmin打造在线教育平台(一)
    Linux环境部署(一)
    centOS的联网问题
  • 原文地址:https://www.cnblogs.com/tandaxia/p/4576017.html
Copyright © 2011-2022 走看看