未为 ChildViewController 更新父变量
Parent variable is not updated for the ChildViewController
我有一个继承自 BaseViewController.swift
的 class。我已经为核心数据更改跟踪定义了一个标志:
var coreDataUpdated: Bool?
我还在 BaseViewController.swift
的 viewWillAppear
中添加了核心数据更改的观察者
//Core data update
NotificationCenter.default.addObserver(self,
selector: #selector(self.CoreDataUpadated),
name: .NSManagedObjectContextObjectsDidChange,
object: nil)
现在,每当我通知核心数据发生变化时,我都会将 coreDataUpdated
变量更改为 true
@objc func CoreDataUpadated() {
self.coreDataUpdated = true
}
现在在我的 ChildViewController.swift
在 viewDidAppear
中检查 coreDataUpdated
它 returns 我 nil
这是我的完整代码:
class BaseViewController: UIViewController {
var coreDataUpdated: Bool?
override func viewWillAppear(_ animated: Bool) {
//Core data update
NotificationCenter.default.addObserver(self,
selector: #selector(self.CoreDataUpadated),
name: .NSManagedObjectContextObjectsDidChange,
object: nil)
}
func CoreDataUpadated() {
self.coreDataUpdated = true
}
}
class ChildViewController: BaseViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
reloadData()
}
func reloadData() {
if super.coreDataUpdated ?? false { //I always get nil for
super.coreDataUpdated
tableView?.reloadData()
}
}
}
注意:我正在使用 Xcode 9 beta 5 和 iOS 11 使用 swift 4。但是此代码在 Xcode 8 和 iOS 10.3 与 swift 3.
Class继承并不意味着子类实例继承超类实例中分配给属性的值。
你有一个 BaseViewController
的实例,它有一个 coreDataUpdated
属性 和一个 ChildViewController
的实例,它有一个 coreDataUpdated
属性因为它继承自 BaseViewController
,但它的 属性 值与 BaseViewController
实例 属性 值无关;它们是不同的对象。
当您说 self.coreDataUpdated = true
时,您是在 BaseViewController
实例 .
上设置 属性
当您说 super.coreDataUpdated
时,您指的是 ChildViewController
实例 中的 coreDataUpdated
属性 定义它是 超类;因为这个 属性 从未被赋值所以它是 nil
.
由于 ChildViewController
不会覆盖 coreDataUpdated
super.coreDataUpdated
与 ChildViewController
实例中的 self.coreDataUpdated
相同,因此您可以重写if
语句为:
func reloadData() {
if self.coreDataUpdated ?? false {
tableView?.reloadData()
}
}
希望这能让人更清楚为什么 coreDataUpdated
是 nil
与其使用您自己的 Bool
,检查 NSManagedObjectContext
实例的 hasChanges
属性 可能更简单。
感谢@Paulw11 的评论,我发现继承不会共享值。所以我使用 KVC
模式作为解决方案。这是我更改后的代码
enum coreDataState: String {
case inserted = "inserted"
case deleted = "deleted"
case updated = "updated"
var description: String {
switch self {
case .inserted: return "inserted"
case .deleted: return "deleted"
case .updated: return "updated"
}
}
}
class BaseViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
//Core data update
NotificationCenter.default.addObserver(self,
selector: #selector(self.CoreDataUpadated),
name: .NSManagedObjectContextObjectsDidChange,
object: nil)
}
func CoreDataUpdated(_ notification: Notification) {
if let userDictionary = notification.userInfo as? Dictionary<String, Any> {
for KV in userDictionary {
if KV.key != "managedObjectContext" {
NSUserDefaultManager.SaveItem(KV.key, key: coreDataUpdateKey)
}
}
}
}
func CoreDataChanged() -> coreDataState? {
if let currentState = NSUserDefaultManager.LoadItem(coreDataUpdateKey) as? String {
NSUserDefaultManager.RemoveItem(coreDataUpdateKey)
return coreDataState(rawValue: currentState)
}
return nil
}
}
class ChildViewController: BaseViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
reloadData()
}
func reloadData() {
if super.CoreDataChanged() != .deleted {
loadData()
tableView?.reloadData()
}
}
}
尽管可以使用其他模式来实现它,例如 delegate
或 override
子 类
中的 CoreDataUpdated
函数
我有一个继承自 BaseViewController.swift
的 class。我已经为核心数据更改跟踪定义了一个标志:
var coreDataUpdated: Bool?
我还在 BaseViewController.swift
viewWillAppear
中添加了核心数据更改的观察者
//Core data update
NotificationCenter.default.addObserver(self,
selector: #selector(self.CoreDataUpadated),
name: .NSManagedObjectContextObjectsDidChange,
object: nil)
现在,每当我通知核心数据发生变化时,我都会将 coreDataUpdated
变量更改为 true
@objc func CoreDataUpadated() {
self.coreDataUpdated = true
}
现在在我的 ChildViewController.swift
在 viewDidAppear
中检查 coreDataUpdated
它 returns 我 nil
这是我的完整代码:
class BaseViewController: UIViewController {
var coreDataUpdated: Bool?
override func viewWillAppear(_ animated: Bool) {
//Core data update
NotificationCenter.default.addObserver(self,
selector: #selector(self.CoreDataUpadated),
name: .NSManagedObjectContextObjectsDidChange,
object: nil)
}
func CoreDataUpadated() {
self.coreDataUpdated = true
}
}
class ChildViewController: BaseViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
reloadData()
}
func reloadData() {
if super.coreDataUpdated ?? false { //I always get nil for
super.coreDataUpdated
tableView?.reloadData()
}
}
}
注意:我正在使用 Xcode 9 beta 5 和 iOS 11 使用 swift 4。但是此代码在 Xcode 8 和 iOS 10.3 与 swift 3.
Class继承并不意味着子类实例继承超类实例中分配给属性的值。
你有一个 BaseViewController
的实例,它有一个 coreDataUpdated
属性 和一个 ChildViewController
的实例,它有一个 coreDataUpdated
属性因为它继承自 BaseViewController
,但它的 属性 值与 BaseViewController
实例 属性 值无关;它们是不同的对象。
当您说 self.coreDataUpdated = true
时,您是在 BaseViewController
实例 .
当您说 super.coreDataUpdated
时,您指的是 ChildViewController
实例 中的 coreDataUpdated
属性 定义它是 超类;因为这个 属性 从未被赋值所以它是 nil
.
由于 ChildViewController
不会覆盖 coreDataUpdated
super.coreDataUpdated
与 ChildViewController
实例中的 self.coreDataUpdated
相同,因此您可以重写if
语句为:
func reloadData() {
if self.coreDataUpdated ?? false {
tableView?.reloadData()
}
}
希望这能让人更清楚为什么 coreDataUpdated
是 nil
与其使用您自己的 Bool
,检查 NSManagedObjectContext
实例的 hasChanges
属性 可能更简单。
感谢@Paulw11 的评论,我发现继承不会共享值。所以我使用 KVC
模式作为解决方案。这是我更改后的代码
enum coreDataState: String {
case inserted = "inserted"
case deleted = "deleted"
case updated = "updated"
var description: String {
switch self {
case .inserted: return "inserted"
case .deleted: return "deleted"
case .updated: return "updated"
}
}
}
class BaseViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
//Core data update
NotificationCenter.default.addObserver(self,
selector: #selector(self.CoreDataUpadated),
name: .NSManagedObjectContextObjectsDidChange,
object: nil)
}
func CoreDataUpdated(_ notification: Notification) {
if let userDictionary = notification.userInfo as? Dictionary<String, Any> {
for KV in userDictionary {
if KV.key != "managedObjectContext" {
NSUserDefaultManager.SaveItem(KV.key, key: coreDataUpdateKey)
}
}
}
}
func CoreDataChanged() -> coreDataState? {
if let currentState = NSUserDefaultManager.LoadItem(coreDataUpdateKey) as? String {
NSUserDefaultManager.RemoveItem(coreDataUpdateKey)
return coreDataState(rawValue: currentState)
}
return nil
}
}
class ChildViewController: BaseViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
reloadData()
}
func reloadData() {
if super.CoreDataChanged() != .deleted {
loadData()
tableView?.reloadData()
}
}
}
尽管可以使用其他模式来实现它,例如 delegate
或 override
子 类
CoreDataUpdated
函数