Core Data详细解析(三) —— 一个简单的入门示例(一)

版本记录

版本号 时间
V1.0 2018.09.21 星期五

前言

数据是移动端的重点关注对象,其中有一条就是数据存储。CoreData是苹果出的数据存储和持久化技术,面向对象进行数据相关存储。感兴趣的可以看下面几篇文章。
1. iOS CoreData(一)
2. iOS CoreData实现数据存储(二)

开始

首先看一下写作环境:

Swift 4.2, iOS 12, Xcode 10

打开Xcode并基于Single View App模板创建一个新的iOS项目。 将应用程序命名为HitList,并确保选中Use Core Data

Core Data详细解析(三) —— 一个简单的入门示例(一)_第1张图片

选中Use Core Data框将导致XcodeAppDelegate.swift中的NSPersistentContainer生成样板代码。

NSPersistentContainer由一组对象组成,这些对象有助于从Core Data中保存和检索信息。 在此容器内部是一个对象,用于管理整个Core Data状态,表示数据模型的对象,等等。

标准堆栈适用于大多数应用程序,但根据您的应用程序和数据要求,您可以自定义堆栈以提高效率。

注意:并非iOS▸Application下的所有Xcode模板都可以选择以Core Data开始。 在Xcode 10中,只有Master-Detail AppSingle View App模板具有Use Core Data复选框。

这个示例应用程序的想法很简单:将有一个table view视图,其中包含您自己的“命中列表”的名称列表。 您将能够为此列表添加名称,并最终使用Core Data确保数据存储在会话之间。 我们不会宽恕这个网站上的暴力,所以你可以把这个应用程序想象成一个收藏列表来跟踪你的朋友,当然!

单击Main.storyboard以在Interface Builder中打开它。 选择画布上的视图控制器并将其嵌入到导航控制器中。 从Xcode的Editor菜单中,选择Embed In… ▸ Navigation Controller

Core Data详细解析(三) —— 一个简单的入门示例(一)_第2张图片

单击导航控制器的导航栏将其选中,然后单击“属性”检查器(Attributes Inspector)中的Prefers Large Titles。 这将为示例应用程序提供与Apple的stock应用程序匹配的标题样式。

Core Data详细解析(三) —— 一个简单的入门示例(一)_第3张图片

接下来,将Table View从对象库拖到视图控制器中,然后调整其大小以覆盖整个视图。

如果尚未打开,请使用画布左下角的图标打开Interface Builder的文档大纲。

按住Ctrl键并从文档大纲中的Table View拖动到其父视图,然后选择Leading Space to Safe Area约束:

Core Data详细解析(三) —— 一个简单的入门示例(一)_第4张图片

再做三次,选择Trailing Space to Safe AreaTop Space to Safe Area,最后选择Bottom Space to Safe Area。 添加这四个约束将使Table View填充其父视图。

接下来,拖动Bar Button Item并将其放在视图控制器的导航栏上。 最后,选择条形按钮项并将其系统项更改为Add

您的画布应类似于以下屏幕截图:

Core Data详细解析(三) —— 一个简单的入门示例(一)_第5张图片

每次点击Add按钮,都会出现包含text fieldalert控制器。 从那里,您将能够在text field中键入某人的姓名。 点击Save将保存名称,关闭alert控制器并刷新Table View,显示您输入的所有名称。

但首先,您需要使视图控制器成为Table View的数据源。 在画布中,按住Ctrl键并从Table View拖动到导航栏上方的黄色视图控制器图标,如下所示,然后单击dataSource

Core Data详细解析(三) —— 一个简单的入门示例(一)_第6张图片

如果您想知道,您不需要设置Table View的代理,因为点击单元格不会触发任何操作。 没有比这更简单的了!

通过按下Command-Option-Enter或在Xcode栏上选择编辑器工具集上的中间按钮打开助理编辑器。

按住Ctrl键从Table View拖动到类定义中的ViewController.swift以创建IBOutlet

Core Data详细解析(三) —— 一个简单的入门示例(一)_第7张图片

接下来,将新的IBOutlet属性命名为tableView,从而生成以下行:

@IBOutlet weak var tableView: UITableView!

接下来,从Add按钮按住Ctrl键并拖动到viewDidLoad()定义正下方的ViewController.swift中。 这一次,使用类型UIBarButtonItem创建一个action而不是IBOutlet,命名方法addName

@IBAction func addName(_ sender: UIBarButtonItem) {
  
}

您现在可以在代码中引用表格视图和条形按钮项目的操作。

接下来,您将为tableView设置模型。 将以下属性添加到ViewController.swifttableViewIBOutlet下面:

var names: [String] = []

names是一个可变数组,用于保存tableView显示的字符串值。 接下来,使用以下内容替换viewDidLoad()的实现:

override func viewDidLoad() {
  super.viewDidLoad()
  
  title = "The List"
  tableView.register(UITableViewCell.self,
                     forCellReuseIdentifier: "Cell")
}

这将在导航栏上设置标题,并使用tableView注册UITableViewCell类。

注意:register(_:forCellReuseIdentifier:)保证当对于dequeue方法提供Cell reuseIdentifier时,您的tableView将返回正确类型的cell。

接下来,仍然在ViewController.swift中,在ViewController的类定义下添加以下UITableViewDataSource扩展:

// MARK: - UITableViewDataSource
extension ViewController: UITableViewDataSource {
  
  func tableView(_ tableView: UITableView,
                 numberOfRowsInSection section: Int) -> Int {
    return names.count
  }
  
  func tableView(_ tableView: UITableView,
                 cellForRowAt indexPath: IndexPath)
                 -> UITableViewCell {

    let cell =
      tableView.dequeueReusableCell(withIdentifier: "Cell",
                                    for: indexPath)
    cell.textLabel?.text = names[indexPath.row]
    return cell
  }
}

如果您曾经使用过UITableView,那么这段代码应该非常熟悉。 首先,将表中的行数作为names数组中的项数返回。

接下来,tableView(_:cellForRowAt :)使表视图单元格出列,并使用names数组中的相应字符串填充它们。

接下来,您需要一种方法来添加新名称,以便tableView可以显示它们。 实现之前按Ctrl键拖动到代码中的addName IBAction方法:

// Implement the addName IBAction
@IBAction func addName(_ sender: UIBarButtonItem) {
  
  let alert = UIAlertController(title: "New Name",
                                message: "Add a new name",
                                preferredStyle: .alert)
  
  let saveAction = UIAlertAction(title: "Save",
                                 style: .default) {
    [unowned self] action in
                                  
    guard let textField = alert.textFields?.first,
      let nameToSave = textField.text else {
        return
    }
    
    self.names.append(nameToSave)
    self.tableView.reloadData()
  }
  
  let cancelAction = UIAlertAction(title: "Cancel",
                                   style: .cancel)
  
  alert.addTextField()
  
  alert.addAction(saveAction)
  alert.addAction(cancelAction)
  
  present(alert, animated: true)
}

每次点击Add按钮时,此方法都会显示一个带有text field和两个按钮SaveCancelUIAlertController

Savetext field当前文本插入到names数组中,然后重新加载表视图。 由于names数组是支持tableView的模型,因此无论您在text field中键入什么内容都将显示在tableView中。

最后,首次构建并运行您的应用程序。 接下来,点击Add按钮。 alert控制器将如下所示:

Core Data详细解析(三) —— 一个简单的入门示例(一)_第8张图片

在列表中添加四个或五个名称。 您应该看到类似于下面的内容:

Core Data详细解析(三) —— 一个简单的入门示例(一)_第9张图片

您的tableView将显示数据,您的数组将存储名称,但这里缺少的是持久化(persistence)。 数组在内存中,但如果您强制退出应用程序或重新启动设备,您的hit list将被清除。 Core Data提供持久性,这意味着它可以将数据存储在更持久的状态,因此它可以比应用程序重新启动或设备重启更久。

您还没有添加任何Core Data元素,因此在您离开应用程序之后不应该保留任何内容。 我们来试试吧。 如果您使用的是物理设备请按Home键或如果您使用的是模拟器使用快捷键(Shift +⌘+ H)。 这将带您回到主屏幕上熟悉的应用网格:

Core Data详细解析(三) —— 一个简单的入门示例(一)_第10张图片

在主屏幕中,点击HitList图标将应用程序带回前台。 名称仍在屏幕上。 发生了什么?

当您点按Home按钮时,当前位于前台的应用会转到后台。 发生这种情况时,操作系统会闪存当前内存中的所有内容,包括names数组中的字符串。 同样,当它唤醒并返回前台时,操作系统会恢复以前在内存中的内容,就好像你永远没离开一样。

Apple在iOS 4中引入了多任务处理的这些功能。它们为iOS用户创造了无缝体验,但却为iOS开发人员的持久性定义增添了一丝曙光。 这些names真的持久化存在了吗?

不,不是真的。 如果您在快速应用程序切换器中完全杀死了应用程序或关闭了手机,那么这些names就会消失。 您也可以验证这一点。 将应用程序置于前台,进入快速应用程序切换器。 您可以通过双击主页按钮来完成此操作,如果您的设备有一个,或者如果您在iPhone X上,则从屏幕底部向上慢慢拖动。

Core Data详细解析(三) —— 一个简单的入门示例(一)_第11张图片

从此处,向上轻拂HitList应用程序快照以终止应用程序。 如果您正在使用iPhone X,则必须长按应用程序快照,直到右上角出现红色删除按钮。

从应用程序切换器中删除应用程序后,在活动内存中应该没有HitList的痕迹。 通过返回主屏幕并点击HitList图标以触发重新启动来验证names是否已消失。

如果您已经使用iOS一段时间并且熟悉多任务处理的工作方式,那么闪存冻结和持久化之间的区别可能是显而易见的。 然而,在用户的心中,没有区别。 用户不关心为什么名称仍然存在,应用程序是否进入后台并返回,或者是因为应用程序保存并重新加载它们。 重要的是当应用程序回来时,名字仍然存在!

因此,持久化的真正考验是在新应用程序启动后您的数据是否仍然存在。

后记

本篇主要讲述了一个简单的入门示例,感兴趣的给个赞或者关注~~~

Core Data详细解析(三) —— 一个简单的入门示例(一)_第12张图片

你可能感兴趣的:(Core Data详细解析(三) —— 一个简单的入门示例(一))