今天是第一周的周五,明显感到时间有些紧张了。按照计划,前两周要完成4个Demo,4个Demo的指导书分别为150页、260页、270页、290页。
由于前几天熬夜复习,状态不佳,目前我第二个Demo只完成了50%+的进度。目前已完成的里程碑是:
01 Playing with table views.
02 Model-View-Controller
03 Adding new items to the checklist
04 The Add Item screen
05 Editing existing checklist items
接下来预计周日之前要完成的里程碑是:
06 Saving and loading the checklist items (起了个头)
07 Multiple checklists
08 Putting to-do items into the checklists
09 Using UserDefaults to remember stuff
10 Improving the user experience
11 Local notifications
吩咐自己一定要在周日前完成Checklists,这样才能早日开启第三个demo,以免进度落伍。
在昨天的基础上,今天比较大的收获是学会使用delegate。
下面说说 创建 delegate 的5个简单步骤:(假设我们拥有Screen A 和 ScreenB )
1. 定义一个delegate protocol for B
2. 在B中定义一个weak optional var (delegate)
3. B send msg to delegate
4. A 遵守 delegate protocol, 实现protocol中定义的的方法
5. tell B that A is its delegate
这样就完成了delegate的创建, B到A的通讯都可以通过delegate来完成。
注意到几下几点:
一、delegate是weak的,弱联系的。
因为对于A和B而言,若互为强联系,容易形成一个ownership cycle,进而易发生Memory Leak。
二、弱联系有什么好处呢? 松耦合! B不需要知道A的全部信息,B只要知道A是它的delegate。
三、IOS的Swift语言中的protocol和我们往常理解的【协议】是不一样的!
Swift中的protocol更近似于面向对象语言中的【接口】!比如下面
// swift中的protocol只是一组方法集合,类似于接口
protocol ItemDetailViewControllerDelegate: class {
func itemDetailViewControllerDidCancel(_ controller: ItemDetailViewController)
func itemDetailViewController(_ controller: ItemDetailViewController,
didFinishAdding item: ChecklistItem)
func itemDetailViewController(_ controller: ItemDetailViewController,
didFinishEditing item:ChecklistItem)
}
四、prepare-for-segue 在 View 显示之前传递数据。这里我们要判断segue的标识符是 AddItem还是 EditItem。 只因为了实现Edit,我们复用了Add的代码
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//1
if segue.identifier == "AddItem" {
//2
let navigationController = segue.destination as! UINavigationController
//3
let controller = navigationController.topViewController as! ItemDetailViewController
//4
controller.delegate = self
} else if segue.identifier == "EditItem" {
let navigationController = segue.destination as! UINavigationController
let controller = navigationController.topViewController as! ItemDetailViewController
controller.delegate = self
if let indexPath = tableView.indexPath(for: sender as! UITableViewCell) {
controller.itemToEdit = items[indexPath.row]
}
}
}
五、Swift语言中为了避免空指针异常,是不允许变量的值为Null或nil的。若要人为地令值为空,可以采用?或!,也就是optional标志。
如果需要使用一个optional常量,需要使用 if let 判断是否为空,为空则直接跳过block。
if let index = items.index(of: item) {
let indexPath = IndexPath(row: index, section: 0)
if let cell = tableView.cellForRow(at: indexPath) {
configureText(for: cell, with: item)
}
}
最后再说一下Xcode的查找匹配机制,真的很好用,可以显示每一段代码修改前后的preview。
遗憾的是,因为我选择了忽略大小写,而不是完全匹配,
因此在修改AddItemViewController为ItemDetailViewController时出现了差错,纠正了很长时间。
如上可知,01-05 体现了一个迭代过程。我们总是在保证不影响已有功能的前提下实施迭代。
接下来的06部分,为了存储用户数据,我们需要了解数据持久化,需要了解IOS的沙盒系统。
IOS的沙盒中有一个Documents文件夹,本App的所有files都存储于此。
在06部分我们要做的主要工作是:
-
Determine where in the file system you can place the file that will remember theto-do list items.
-
Save the to-do items to that file whenever the user changes something: adds anew item, toggles a checkmark, deletes an item, et cetera.
-
Load the to-do items from that file when the app starts up again after it wasterminated.