Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.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 回调违反了控制反转_Ios_Swift_Callback_Inversion Of Control_Combine - Fatal编程技术网

Ios 回调违反了控制反转

Ios 回调违反了控制反转,ios,swift,callback,inversion-of-control,combine,Ios,Swift,Callback,Inversion Of Control,Combine,如果我对IOC的理解正确,这意味着您配置用于驱动功能的任何框架或模块都应该能够在需要时驱动代码(参考:)。这意味着控制是框架驱动的 我正在浏览一个很棒的博客。博客一开始就说,通过回调或闭包处理异步行为违反了IOC。我有点不同意这个说法,但我只是想澄清我的理解 情景: 我创建了一个TestFramework,它为框架用户处理一些功能 public class TestFramework { typealias UpdatedFrameworkData = (FrameworkData?)

如果我对IOC的理解正确,这意味着您配置用于驱动功能的任何框架或模块都应该能够在需要时驱动代码(参考:)。这意味着控制是框架驱动的

我正在浏览一个很棒的博客。博客一开始就说,通过回调或闭包处理异步行为违反了IOC。我有点不同意这个说法,但我只是想澄清我的理解

情景:

我创建了一个
TestFramework
,它为框架用户处理一些功能

public class TestFramework {

    typealias UpdatedFrameworkData = (FrameworkData?) -> Void

    var giveUpdatedValues: (() -> UpdatedFrameworkData)?

    init() { }

    private func someAction() {
        var updatedValuesCallback = giveUpdatedValues?()
        updatedValuesCallback = { [weak self] updatedFrameworkData in
            // Perform some action

        }
    }
}
现在我有了一个使用这个框架的类

class FrameworkUser {
    let framework: TestFramework = TestFramework()
    var updatedValuesCallback: TestFramework.UpdatedFrameworkData?

    init() {
       setupBinding()
    }

    private func setupBinding() {
        updatedValuesCallback = framework.giveUpdatedValues?()
    }

    private func getUpdatedData(completion: @escaping TestFramework.UpdatedFrameworkData) {
        // Return some data
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            self.updatedValuesCallback?(self.getFrameworkData())
        }
    }

    private func getFrameworkData() -> FrameworkData? {
        nil
    }
}
该框架有时可能需要处理更新的数据,而不是一些陈旧的数据。如果您观察我的框架,那么它仍然可以控制何时通过用户提供的侦听器获取更新数据的功能。用户通过异步回调向框架提供数据

那么,在这种情况下,我是不是通过回调实现了国际奥委会的目标,还是遗漏了什么

编辑:

我在上面的设置绑定代码中犯了一个小错误。用户仍然调用框架以提供更新的值

我对上面的代码做了以下修改,以发现回调对程序的异步处理确实违反了IOC原则。上面的
setupBinding()
方法在绑定到框架回调的方式上不正确。应该是这样的:

private func setupBinding() {
        framework.giveUpdatedValues = {
            return getUpdatedData() // This won't work
        }
    }

为了遵循IOC原则,用户应该将其代码绑定到框架回调。上面的代码根本不起作用,因为您不能简单地从函数返回一个转义闭包,这个闭包将在以后的某个时间轴中执行。

闭包和协议在语义上是相同的,即使它们在语法上是不同的。如果闭包违反IOC,那么协议也会违反IOC。由于IOC的经典示例使用协议,这意味着语义相同的闭包不会违反协议

为了证明它们是相同的:

protocol FrameworkDelegate { 
    func myFunc(data: Int)
}

class Framework {
    weak var delegate: FrameworkDelegate?

    func example() {
        delegate?.myFunc(5)
}

vs


上面两个代码示例之间的唯一区别是什么对象确保了
委托
不会拒绝。在这两种情况下,
Framework
的用户定义在框架类型确定何时调用“委托方法”时发生的情况。

闭包和协议在语义上是相同的,即使它们在语法上是不同的。如果闭包违反IOC,那么协议也会违反IOC。由于IOC的经典示例使用协议,这意味着语义相同的闭包不会违反协议

为了证明它们是相同的:

protocol FrameworkDelegate { 
    func myFunc(data: Int)
}

class Framework {
    weak var delegate: FrameworkDelegate?

    func example() {
        delegate?.myFunc(5)
}

vs


上面两个代码示例之间的唯一区别是什么对象确保了
委托
不会拒绝。在这两种情况下,
Framework
的用户定义了当框架类型决定何时调用“委托方法”时发生的事情。

我认为第二个链接是说用回调闭包(也称为完成处理程序)实现的异步操作违反了IoC,而不是闭包本身。@Sweeper感谢指出这一点。用适当的例子编辑了这个问题。我认为第二个链接是说用回调闭包(又称完成处理程序)实现的异步操作违反了IoC,而不是闭包本身。@Sweeper感谢您指出了这一点。用适当的例子编辑了这个问题正如@sweeper在其中一条评论中指出的,作者在博客中谈到了使用回调的异步编程。在我在问题中提到的代码中,您可以观察future的回调
giveUpdatedValues:(()->UpdatedFrameworkData)?
将回调返回给提供更新数据的框架。此回调由异步进程从用户端调用。我认为作者认为从用户端调用
updatedValuesCallback()
违反了IOC,因为当数据可用时,用户再次调用框架。有趣的是,在这篇演讲()中,演讲者断言异步回调进行反向控制,这就是它们的问题所在!他解释了为什么他们会反转控制,而你引用的文章只是在没有任何解释的情况下声明。马丁·福勒的文章也使用回调来显示控制反转。当然,他是在UI引擎的上下文中这样做的,但是如果Tk通过网络发送请求,并在一台完全不同的计算机上显示输入窗口,那么这是否意味着IOT会突然被相同的代码破坏?我认为不是。正如@sweeper在其中一条评论中指出的,作者在博客中谈到了使用回调的异步编程。在我在问题中提到的代码中,您可以观察future的回调
giveUpdatedValues:(()->UpdatedFrameworkData)?
将回调返回给提供更新数据的框架。此回调由异步进程从用户端调用。我认为作者认为从用户端调用
updatedValuesCallback()
违反了IOC,因为当数据可用时,用户再次调用框架。有趣的是,在这篇演讲()中,演讲者断言异步回调进行反向控制,这就是它们的问题所在!他解释了为什么他们会反转控制,而你引用的文章只是在没有任何解释的情况下声明。马丁·福勒的文章也使用回调来显示控制反转。当然,他是在UI引擎的上下文中这样做的,但是如果Tk通过网络发送请求,并在一台完全不同的计算机上显示输入窗口,那么这是否意味着IOT会突然被相同的代码破坏?我想不是。