objective-c - 应用程序终止时尝试保存到 plist

标签 objective-c ios xcode ios5

好的,我目前有一个主从应用程序,它有一个带有导航 Controller 的 TableView 、一个详细 View 和一个模态视图。导航 View 显示饮料名称,详细 View 显示所选饮料的详细信息,模态视图允许我创建新饮料或编辑现有饮料。一切都是从我已经移动到文档目录的 plist 中填充的,一切都很好地从中读取。我知道这是有效的,因为我已经用一个空的 plist 进行了测试,看看我的 View 是否变为空白,并且它们成功了。我所有的观点都完美无缺。我可以添加编辑和删除饮料,并且我的表格 View 会使用新的、删除的或更改的饮料进行更新。但是它没有成功写入 plist 文件(我正在从我的 masterViewController 中名为“drinks”的数组更新我的 plist)。我认为这是因为我试图在我的 MasterViewController 内部而不是在我的 AppDelegate.m 中使用下面的这个方法

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [searchPaths objectAtIndex:0];
    NSString *writeableDBPath = [documentsDirectory stringByAppendingPathComponent:@"DrinkDirections.plist"];

    [self.drinks writeToFile:writeableDBPath atomically:YES];
}

我已经通过放置 2 个 NSLogs() 来对此进行了测试:一个在 我放置在 我的 masterViewController 中的 applicationWillTerminate 方法中,一个在我的 AppDelegate.m 中的 applicationWillTerminate 方法中。该日志仅显示在 AppDelegate.m 中的控制台中。所以最后我不知道如何从我的 AppDelegate.m 文件访问我的 MasterViewController 中的饮料数组,所以我可以使用我的 appDelegate.m 中的 applicationWillTerminate 方法保存到 plist。我将在下面发布我的 appDelegate.m 代码,该代码会引发错误,因为 drinks 属性位于 MasterViewController 中。

AppDelegate.m(方法)

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [searchPaths objectAtIndex:0];
    NSString *writeableDBPath = [documentsDirectory stringByAppendingPathComponent:@"DrinkDirections.plist"];

    [self.drinks writeToFile:writeableDBPath atomically:YES]; //THIS LINE THROWS AN ERROR BECAUSE PROPERTY DRINKS IS ONLY ON MY MASTERVIEWCONTROLLER NOT MY AppDelegate

}

最佳答案

首先,正如此处其他人所提到的,applicationDidEnterBackground: 可能是执行此操作的更好位置。其次,您的 View Controller 不会独自获得此调用:它是一个 UIApplicationDelegate 协议(protocol)调用,而您的 View Controller 不是其中之一。

您要做的是让您的 View Controller 收到 UIApplicationDidEnterBackgroundNotification 通知。 The UIApplicationDelegate reference说:

The application also posts a UIApplicationDidEnterBackgroundNotification notification around the same time it calls this method to give interested objects a chance to respond to the transition.

所以在你的 View Controller 中你想做这样的事情(警告:将这段代码直接输入网页,不要尝试编译它):

- (void) viewDidLoad
{
    [super viewDidLoad];

    // Register for notification.
    [[NSNotificationCenter defaultCenter] addObserver:self 
                          selector:@selector(applicationDidEnterBackground:) 
                              name:UIApplicationDidEnterBackgroundNotification
                            object:nil];
}

- (void) viewDidUnload
{
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
}

- (void) applicationDidEnterBackground:(NSNotification*)notification 
{
    // Do your plist saving here.
}

关于objective-c - 应用程序终止时尝试保存到 plist,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11217549/

相关文章:

ios - XMPP、CoreData - 如何仅加载自身和目标用户消息?

ios - Objective c UIImageView 动画

objective-c - 如何克隆类实例并仅更改 Objective C 或 Swift 中的一个字段?

ios - 意外的类型名称“BOOL”:iOS SDK 6.1(设备)中的预期表达式

ios - UITableViewCell 使用复选标记作为切换开关

ios - 将数据返回给第一个 ViewController

ios - 如何将 eng.cube.lm 放入 xcode 5.0.2

ios - AlamofireObjectMapper 在 iOS 8 中不工作

ios - 无法将 SKEffectNode 视为具有建议效果的 child

swift - tableview 没有用导航栏填满 Storyboard 中的整个屏幕