ios - Swift 中的闭包,Objective-C 中的 block : their usefulness and when to use

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

我找到了一个 Objective-C SocketIO library并尝试在我的第一个 Swift 应用程序中实现它。这是我要移植的代码:

__weak typeof(self) weakSelf = self;
self.socket.onConnect = ^()
{
    weakSelf.socketIsConnected = YES;
    [weakSelf mapView: weakSelf.mapView didUpdateUserLocation: weakSelf.mapView.userLocation];
};

根据我有限的理解,^() {} 是 Objective C 中的一个 block 。我已经研究过它并且 closures seem to be a loose equivalent Swift .我的第一个明显问题是如何在 Swift 中获得相同的结果?

我已经尝试了以下但得到了错误fatal error: unwrappingly found nil while unwrapping an Optional value (lldb):

self.socket.onConnect = { () -> Void in
    println("Connected!")
}

此外,幕后发生了什么?异步回调函数似乎合适但未被使用,我想了解原因。

更新

正如@jtbandes 所指出的,socket 实际上是 Nil,因为这段代码在连接回调之外运行(我知道,这是一个非常愚蠢的错误)。第一个问题的解答:

SIOSocket.socketWithHost(server) { (socket: SIOSocket!) in
    self.socket = socket

    self.socket.onConnect = { () -> Void in
        println("Connected!")
    }
}

最佳答案

Objective-C block 和 Swift 闭包不仅仅是松散的等价物。它们是直接等效的。

block /闭包是一个匿名函数,它继承了它的封闭范围。

我仍在使用 Objective-C,所以我已经习惯了它的术语。我将使用这些术语

block 在很多方面都很有用。

完成代码是一个例子。

没有 block ,如果你正在设置一个异步网络类,你可以给它一个委托(delegate)属性,并定义一个带有回调的协议(protocol),该类用来通知它的委托(delegate)有关下载完成、错误等事件。

这使得在许多不同的地方有大量的消息处理基础设施。你必须定义一个协议(protocol)。您必须向网络类添加委托(delegate)属性。您必须在客户端类中实现一组委托(delegate)消息。您可能必须将上下文信息传递给回调等。

使用 block ,您可以调用一个请求网络服务的方法,并提供一个完成 block 。服务完成后,它会调用提供的代码块。您可以向完成 block 添加参数,例如指向数据的指针、成功 bool 值或任何合适的参数。代码块可以访问其封闭范围内定义的所有变量,这非常有帮助。

还可以将 block 保存到集合中,可以在排序方法中使用 block ,还有很多其他情况。

您发布的代码只是在相关对象 self.socket 上设置了一个 block 属性。看起来这是一段代码,在建立套接字连接后被调用。

在 Swift 中有直接的等价物。不过,我只是在 Swift 中四处闲逛,所以我会把它留给其他人来帮助您进行翻译。

我建议浏览 Apple 的类(class),了解如何使用 block 。如果您对异步网络感兴趣,请查看 NSURLConnection 和 NSURLSession。看一下采用动画 block 和完成 block 的基于 block 的 View 动画方法。这些将使您了解如何使用 block 来处理异步事件,或将代码传递给类以完成工作。

block 的另一个有趣用途是处理数组等集合。有些方法采用 NSComparator block 并对数组进行排序,有些方法将枚举整个数组,对每个元素执行代码块和/或选择元素的子集并返回数组索引的索引集.

邓肯

关于ios - Swift 中的闭包,Objective-C 中的 block : their usefulness and when to use,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27238050/

相关文章:

iphone - 动画日期选择器。有可能吗?

ios - 在 Objective-c 问题中访问委托(delegate)静态方法

ios - 我的 fetchRequest 返回的数据不在我的数据库中,为什么?

iphone - 是否可以将 Localytics 与 Mono for iOS 一起使用?

iphone - 帮助在iPhone上实时更新声音

objective-c - 为什么仪器找不到这个泄漏点?

swift 2.1 : Unable to map JSON object to Realm object using ObjectMapper

swift - 确定 swift 对象是否具有父类(super class)

ios - 如何创建展开和折叠表格 View ?

ios - 如何修改或更改 PopoverPresentationController 的大小?