Полагаю, я использую (вроде) тот же подход, что и младший. Я опубликую его для образовательных целей.
У меня есть протокол, который выглядит следующим образом:
FSViewControllerRestoration.h
#import <Foundation/Foundation.h>
@protocol FSViewControllerStateRestoration <NSObject>
@required;
- (NSDictionary *)currentState;
- (void)restoreState:(NSDictionary *)state;
@end
У меня также есть класс, который используется для загрузки и хранения стека контроллера представления.При загрузке стека контроллера представления он проверяет, соответствует ли класс протоколу, и если это так, вызывает метод restoreState:.
FSViewControllerStorage.h
#import <Foundation/Foundation.h>
#import "FSViewControllerStateRestoration.h"
@interface FSViewControllerStateStorage : NSObject
+ (BOOL)storeViewControllerStack:(NSArray *)stack;
+ (NSArray *)loadViewControllerStack;
@end
FSViewControllerStorage.m
#import "FSViewControllerStateStorage.h"
#define FS_PATH_APPLICATION_STATE_FILE [FS_PATH_DOCUMENTS_DIR stringByAppendingPathComponent:@"appstate.dat"]
@implementation FSViewControllerStateStorage
+ (BOOL)storeViewControllerStack:(NSArray *)stack
{
DLog(@"storing view controller stack ...");
if (stack.count <= 1)
{
return [NSKeyedArchiver archiveRootObject:nil toFile:FS_PATH_APPLICATION_STATE_FILE];
}
NSArray *items = @[];
for (UIViewController *viewController in stack)
{
NSString *className = NSStringFromClass(viewController.class);
NSDictionary *state = @{};
if ([viewController conformsToProtocol:@protocol(FSViewControllerStateRestoration)])
{
state = [(id <FSViewControllerStateRestoration>)viewController currentState];
}
items = [items arrayByAddingObject:@{@"Class" : className, @"State" : state}];
}
return [NSKeyedArchiver archiveRootObject:items toFile:FS_PATH_APPLICATION_STATE_FILE];
}
+ (NSArray *)loadViewControllerStack
{
DLog(@"loading view controller stack ...");
NSArray *items = [NSKeyedUnarchiver unarchiveObjectWithFile:FS_PATH_APPLICATION_STATE_FILE];
NSArray *stack = @[];
for (NSDictionary *dictionary in items)
{
NSString *className = [dictionary objectForKey:@"Class"];
NSDictionary *state = [dictionary objectForKey:@"State"];
Class class = NSClassFromString(className);
UIViewController *viewController = [[class alloc] init];
if ([viewController conformsToProtocol:@protocol(FSViewControllerStateRestoration)])
{
[(id <FSViewControllerStateRestoration>)viewController restoreState:state];
}
stack = [stack arrayByAddingObject:viewController];
}
return stack;
}
@end
В моем AppDelegate используется класс храненияследующим образом ...
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[FSViewControllerStateStorage storeViewControllerStack:self.navigationController.viewControllers];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSArray *viewControllers = [FSViewControllerStateStorage loadViewControllerStack];
if (viewControllers.count > 0)
{
self.navigationController.viewControllers = viewControllers;
}
}
И, наконец, пример сохранения и восстановления состояния в viewController, соответствующем протоколу:
#pragma mark - View controller state restoration
- (NSDictionary *)currentState
{
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
if (_newsItem)
{
[dictionary setObject:_newsItem forKey:@"NewsItem"];
}
if (_comments)
{
[dictionary setObject:_comments forKey:@"Comments"];
}
return dictionary;
}
- (void)restoreState:(NSDictionary *)state
{
FSNewsItem *newsItem = [state objectForKey:@"NewsItem"];
if (newsItem)
{
self.newsItem = newsItem;
}
NSArray *comments = [state objectForKey:@"Comments"];
if (comments)
{
self.comments = comments;
}
}