Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
IOS-SWIFT-如何解决苹果文档代码中关于KVO的警告?为什么Xcode自动更正会引入错误?_Ios_Swift_Xcode_Key Value Observing - Fatal编程技术网

IOS-SWIFT-如何解决苹果文档代码中关于KVO的警告?为什么Xcode自动更正会引入错误?

IOS-SWIFT-如何解决苹果文档代码中关于KVO的警告?为什么Xcode自动更正会引入错误?,ios,swift,xcode,key-value-observing,Ios,Swift,Xcode,Key Value Observing,为了学习KVO,我从中复制了代码。详情如下: class MyObjectToObserve: NSObject { @objc dynamic var myDate = NSDate(timeIntervalSince1970: 0) // 1970 func updateDate() { myDate = myDate.addingTimeInterval(Double(2 << 30)) // Adds about 68

为了学习KVO,我从中复制了代码。详情如下:

 class MyObjectToObserve: NSObject {
        @objc dynamic var myDate = NSDate(timeIntervalSince1970: 0) // 1970
        func updateDate() {
            myDate = myDate.addingTimeInterval(Double(2 << 30)) // Adds about 68 years.
        }
    }

    class MyObserver: NSObject {
        @objc var objectToObserve: MyObjectToObserve
        var observation: NSKeyValueObservation?

        init(object: MyObjectToObserve) {
            objectToObserve = object
            super.init()

            observation = observe(
                \.objectToObserve.myDate,
                options: [.old, .new]
            ) { object, change in
                print("myDate changed from: \(change.oldValue!), updated to: \(change.newValue!)")
            }
        }
    }

    let observed = MyObjectToObserve()
    let observer = MyObserver(object: observed)

    observed.updateDate()
第二行到最后一行将导致警告,因为未使用observer。在我按照Xcode的建议将let observer替换为u之后,警告消失了,但它将给出一个运行时错误:

线程1:EXC_BAD_访问代码=EXC_I386_GPFLT

我的目标是回答以下问题:

1.有人知道它为什么会导致错误吗

2.如何解决警告


3.此示例是否是Swift中KVO的最新示例?语法级别

苹果文档中的代码片段只是一个示例——这不是一个完整的实现

据推测,您将使用observer执行其他操作,此时您将不再收到未使用的警告

示例用法仅用于演示,不被视为生产代码:

class ExampleViewController: UIViewController {

    var observed: MyObjectToObserve!
    var observer: MyObserver!

    override func viewDidLoad() {
        super.viewDidLoad()

        observed = MyObjectToObserve()
        observer = MyObserver(object: observed)

    }

    @IBAction func didTap(_ sender: Any) {
        observed.updateDate()
    }

}
创建一个新的视图控制器;将其类设置为ExampleViewController;添加一个按钮并将其连接到@IBAction func didTap


运行应用程序。。每次点击按钮,您都会在调试控制台中看到打印输出。

讽刺的是,苹果的示例比它需要的更复杂。也就是说,MyObserver对象甚至不是必需的。您只需对实际观察的对象调用“观察”

如下所示:

class MyObjectToObserve: NSObject {
    @objc dynamic var myDate = NSDate(timeIntervalSince1970: 0) // 1970
    func updateDate() {
        myDate = myDate.addingTimeInterval(Double(2 << 30)) // Adds about 68 years.
    }
}

let observed = MyObjectToObserve()
let observation = observed.observe(\MyObjectToObserve.myDate, options: [.old, .new]) { object, change in
    print("myDate changed from: \(change.oldValue!), updated to: \(change.newValue!)")
}

observed.updateDate()
希望编译器能够优化它,如果不是的话,它只是分配一个整数,这样开销可以忽略不计,但它确实可以抑制警告。我添加了注释,以便下一个查看代码的程序员不会删除看似无用的行


注意:我很少再使用KVO了,因为我发现Combine功能更强大,麻烦更少。然而,有时它仍然是必要的。即使在大多数情况下,我的代码看起来更像@DonMag的代码,其中对必需对象的引用作为控制器的成员保留。在我的一些单元测试中,我确实使用了这种抑制攻击,我正在手动设置KVO,不希望我的代码显示警告。

使用您的observer对象。很简单。请看我编辑的答案。我的第一个问题如何?你知道我为什么会出错吗?第一个问题对我来说必须更大你是指使用=myobserver对象:observed时的错误吗?这是因为MyObserver对象需要存在——如果不将其分配给任何对象,则其代码超出范围。这是有意义的。我还尝试将observer设置为可选,并在var observer:MyObserver=MyObserver对象:observed之后将其设置为nil。它给了我同样的崩溃信息。我想,不知何故,KVO需要将MyObserver对象保存在内存中。如果我错了,请纠正我。这让我对观察函数在内存中的工作方式感到好奇,因为观察似乎是在内存中的两个类对象之间创建某种关系的唯一方法
_ = observation.hash    // Suppress warning on observation