littleJoe

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Big Nerd iOS Programming 第18章 Saving,Loading and Application States

18章 Saving,Loading and Application States
    Application Sandbox
    Constructing a file path
    NSKeyedArchiver and NSKeyedUnarchiver


    Application States and Transitions

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

存档 
1.Archiving,永久存储数据。
Archiving:记录并存储属性
Unarchiving:从数据中重新重新创建对象。


实现NSCoding协议,实现两个方法 encodeWithCoder:, initWithCoder:


    - (void)encodeWithCoder:(NSCoder *)aCoder
{
   [aCoder encodeObject:self.itemName forKey:@"itemName"];
   [aCoder encodeObject:self.serialNumber forKey:@"serialNumber"];
   [aCoder encodeObject:self.dateCreated forKey:@"dateCreated"];
   [aCoder encodeObject:self.itemKey forKey:@"itemKey"];


   [aCoder encodeInt:self.valueInDollars forKey:@"valueInDollars"];
}


-(instancetype) initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if(self){
_itemName = [aDecoder decodeObjectForKey:@"itemName"];
}
return self;
}


2.应用沙箱, Application sandbox
程序的数据,缓存等。 不能访问其他应用的沙箱


!!!!!!!!!存储路径!!!!!!!!!!
-(NSString *)itemArchivePath
{
NSArray *documentDirectories = 
NSSearchPathForDirectoriesInDomain(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentDirectiry = [documentDirectories firstObject];
return [documentDirectories stringByAppendingPathComponent:@"items.archive"];


}


**************上面的到了存储的路径,以及药存储的模型数据。那什么时候出发存储已经什么时候加载数据呢?******************


1.存储: 
使用NSKeyedArchiver when application exits.


eg. BNRItem
-(BOOL) saveChanges
{
NSString *path = [self itemArchivePath];
return [NSKeyedArchiver archiveRootObject:self.privateItems];
}


!archiveRootObject:toFile: 工作流程:
1.创建NSKeyedArchiver 对象
2.privateItems发送消息 encodeWithCoder: 并且把 NSKeyedArchiver的对象作为参数。
3.privateItems发送每个其中的字对象  encodeWithCoder,并且传入 NSKeyedArchiver
4.NSKeyedArchiver 写数据到系统文件夹中




当按下home键,applicationDidEnterBackground:会发送到applicationDelegate中,你可以在其中调用saveChanges
它会存在系统文件夹下,一个document文件夹中 item.archive


加载!!:
-(instancetype)initPrivate
{
self = [super init];
if(self){
NSString *path = [self itemArchivePath];
_privateItems = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
if(!_privateItems){
_privateItems = [[NSMutableArray alloc] init];
}
}
return self;
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------
~~~~~~~~~~~~~~~~~~
Application State and Transitions

Writing to the Filesystem with NSData

 NSNotificationCenter and Low-Memory Warnings

Model-View-Controller Store Design Pattern

    Cur:Application States Transitions
    Cur:Reading and Writing to the Filesystem
    Cur:the application bundle


Application State and Transitions
    当按下home键,应用进入后台,进入 background state,理解应用时如何在各个状态之间切换的:
        Not Running 
            -->Application Launches 
                    application:willFinishLaunchingWithOptions:
                    application:didFinishLaunchingWithOptions:
                    applicationDidBecomeActive:
        Active
            -->Home Button Pressed or incoming phone call
                    applicationWillResignActive:
        Inactive
            --->applicationDidEnterBackground:
        Background
            ---> After 5 seconds
        Suspended
            --->Application icon tapped
                    applicationWillEnterForeground:applicationDidBecomeActive:
            ---> system runs low on memory


当状态变化时,delegate会收到以上的一些信息,你可以在其中做些操作,比如保存数据等,


用NSData写入数据

保存图片
    -(NSString *)imagePathForKey:(NSString *)key
    {
        NSArray *documentDirectories = 
            NSSearchPathForDirectoriesInDomain(NSDocumentDirectory,NSUserDomainMask,YES);
        NSString *documentDirectory = [documentDirectories firstObject];
        return  [documentDirectory stringByAppendingPathComponent:key];

    }

// add a image to file system
    -(void)setImage:(UIImage *)image forKey:(NSString *)key
    {
        self.dictionary[key] = image;
        NSString *imagePath = [self imagePathForKey:key];
        NSData *data = UIImagegJPEGRepresentation(image,0.5);

        //write it to full path
        [data writeToFile:imagePath atomically:YES];
    }

// remove from file system
    -(void)deleteImageForKey:(NSString *)key
    {

        if(!key){
            return;
        }
        [self.dictionary removeObjectForKey:key];

        NSString *imagePath = [self imagePathForKey:key];
        [[NSFileManager defaultManager] removeItemAtPath: iamgePath error:nil];
    }

// load image from system
    -(UIImage *)imageForKey:(NSString *)key
    {
        // if posibble ,get it from dictionary
        UIImage *result = self.dictionary[key];
        if(!result){
            NSString *imagePath = [self imagePathForKey:key];
            result = [UIImage imageWithContentsOfFile:imagePath];

            // replace the cache
            if(result){
                self.dictionary[key] = result;
            }else{
                NSLog(@"Error, unable to fine %@", [self imagePathForKey:key]);
            }
        }
        return result;
    }

--------------------------------
通知中心,低内存警告⚠

    viewController收到    didReceiveMemoryWarning。
    你可以在其中清空掉图片缓存dictionary,待需要的时候再加载

你可以添加观察者,例如在BNRImageStore中:
    -(instancetype)init
    {
        self = [super init];
        if(self){
            _dictionary = [[NSMutableDictionary alloc] init];

            NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
            [nc addObserver:self selector:@selector(clearCache:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
        }
        return self;
    }

delegate中的函数应该也是这样注册而来的

    -(void)clearCache:(NSNotification *)note
    {
        NSLog(@"flushing %d images out of the caches",[self.dictionary count]);
        [self.dictionary removeAllObjects];
    }

注意,此时如果没有显示或者没有被引用到的图片缓存将清除,如果当前正在显示,则等不显示到时候再🆑清除。 需要到时候自己再手动加载。

NSNotificationCenter.每个notification都有一个名字

可以在通知中带数据, 上面note 可以访问 userInfo。像cocos2d中的事件getUserData吧

Model-View-Controller-Store

Model表示数据的模型,而Store则正在的存储数据到本地,访问数据库等。
Model表示了比如一个carItem的数据模型:
    NSString *name;
    NSString *productYear;
    double price;

每个carItem作为store中dictionary的子项被存储到本地文件中

**当你够建一个应用程序的时候,会自动创建一个 application bundle,其中包括了所有可执行待代码,图片,音频资源等等。所有程序在执行时用到的资源

你可以通过bundle来获取资源
NSBundle *applicationBundle = [NSBundle mainBundle];
NSString *path = [applicationBundle pathForResource:@"myImage" ofType:@"png"];

 这些都是只读的。不能在运行的时候修改或者添加资源,

 

posted on 2015-02-04 23:13  littleJoe  阅读(98)  评论(0)    收藏  举报