【问题标题】:Difference between block (Objective-C) and closure (Swift) in iOSiOS中块(Objective-C)和闭包(Swift)之间的区别
【发布时间】:2014-12-10 01:44:07
【问题描述】:

在教程中写到在功能上两者都是相同的,甚至闭包比阻塞更容易,并且它避免了块和内存管理的复杂性,我已经阅读了许多教程,但除了这些我没有得到 swift 之间的区别“闭包”和Objective-C“块”。

【问题讨论】:

  • 用“复选标记”标记答案是 StackOverflow 的预期行为。如果提供的答案不能满足您的需求,请对答案发表评论。

标签: ios objective-c swift closures objective-c-blocks


【解决方案1】:

显示差异的实际代码示例:

这确实编译:

let x : @convention(swift) (inout Int) -> ()

这不是:

let y : @convention(block) (inout Int) -> ()

出现错误(inout Int) -> () is not representable in Objective-C

【讨论】:

  • 您不能使用 inout,因为 Objective-C 调用约定没有引用,并且引用和指针之间的转换不是隐式的。不过它确实有指针,所以你将不得不使用UnsafePointer<Int>.. 这使得两个签名相同。
  • @Brandon 如前所述,如果您非常确定块和闭包是相同的,请写信给 Swift 开发人员,他们应该更改他们语言的文档,因为您认为这是错误的;)跨度>
  • @Brandon,1 小时前:“块和闭包是一样的”source; “[...] 这并不意味着它 [a block] 不是一个闭包。” source。 “Swift 中的闭包类似于 C 和 Objective-C 中的块”,Swift doc source
  • @Brandon 同样在同一页上:“函数中介绍的全局和嵌套函数实际上是闭包的特殊情况。”而你说:“函数根本不是一种特殊类型的闭包”source
  • Lol.. 我的声明只是重新强化了您刚刚从 Swift 文档中读到的内容。它们不仅相似,而且是一回事。他们都是NSBlock。所以再一次,告诉我我错在哪里。根据定义,函数和闭包是同一个(维基百科)。但是,不是通过组装。它们的实现方式不同。闭包通过“Invoke”调用。通过将参数压入寄存器和堆栈中直接调用函数。闭包通过objc_msgSend 调用,它在运行时动态地将参数推送到堆栈上。如果您不知道更好,请保持安静。
【解决方案2】:

略有不同。提到了一个;变量被捕获为变量,而不是值。这可能是有用的,也可能是陷阱。重要的是,您可以在 Swift 闭包中定义一个捕获列表,因此如果您在捕获列表中包含 self.property,那么该属性的值将被捕获,而不是 self。这也简化了捕获弱变量的过程。

【讨论】:

    【解决方案3】:

    摘自:Apple Inc.“将 Swift 与 Cocoa 和 Objective-C 结合使用”。 iBooks:

    “Swift 闭包和 Objective-C 块是兼容的,所以你可以将 Swift 闭包传递给期望块的 Objective-C 方法。 Swift 闭包和函数具有相同的类型,因此您甚至可以传递 Swift 函数的名称。

    闭包具有与块相似的捕获语义,但在一个关键方面有所不同:变量是可变的而不是复制的。换句话说,Objective-C 中 __block 的行为是 Swift 中变量的默认行为。”

    【讨论】:

    • 感谢您的解释。
    • @GoZoner,你能用一些例子详细说明第二个语句吗?
    • > 作为一种优化,Swift 可能会捕获并存储一个值的副本,如果该值没有被闭包改变,并且在创建闭包后该值没有改变。 docs.swift.org/swift-book/LanguageGuide/Closures.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-07
    • 2011-12-28
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    相关资源
    最近更新 更多