Ios Swift中的闭包,Objective-C中的块:它们的用途和使用时间

Ios Swift中的闭包,Objective-C中的块:它们的用途和使用时间,ios,objective-c,swift,closures,objective-c-blocks,Ios,Objective C,Swift,Closures,Objective C Blocks,我已经找到了Objective-C,并试图在我的第一个Swift应用程序中实现它。以下是我尝试移植的代码: __weak typeof(self) weakSelf = self; self.socket.onConnect = ^() { weakSelf.socketIsConnected = YES; [weakSelf mapView: weakSelf.mapView didUpdateUserLocation: weakSelf.mapView.userLocatio

我已经找到了Objective-C,并试图在我的第一个Swift应用程序中实现它。以下是我尝试移植的代码:

__weak typeof(self) weakSelf = self;
self.socket.onConnect = ^()
{
    weakSelf.socketIsConnected = YES;
    [weakSelf mapView: weakSelf.mapView didUpdateUserLocation: weakSelf.mapView.userLocation];
};
从我有限的理解来看,
^(){}
是Objective C中的一个块。我已经对它进行了研究并进行了分析。我的第一个明显的问题是如何在Swift中获得相同的结果

我尝试了以下操作,但出现错误
致命错误:在展开可选值(lldb)时意外发现nil

还有,在幕后发生了什么?异步回调函数似乎很合适,但没有使用,我想了解原因

更新

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

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

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

Objective-C Block和Swift Closes不仅仅是松散的等价物。它们是直接等价物

块/闭包是继承其封闭范围的匿名函数

我还在Objective-C工作,所以我习惯了它的术语。我将使用这些术语

块在很多方面都很有用

完成代码就是一个例子

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

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

对于块,您调用一个请求网络服务的方法,并提供一个完成块。当服务完成时,它调用提供的代码块。您可以向完成块添加参数,如指向数据的指针、成功布尔值或任何适当的参数。代码块可以访问其封闭范围中定义的所有变量,这非常有用

您还可以将块保存到集合中,可以在排序方法中使用块,以及在许多其他情况下使用块

您发布的代码只是在有问题的对象self.socket上设置了一个块属性。它看起来像是在建立套接字连接后调用的代码块

在Swift中有直接的等价物。不过,我只是在Swift中进行了尝试,所以我将把它留给其他人来帮助您进行翻译

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

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


邓肯

self.socket
nil?@jtbandes是的!谢谢:)谢谢你提供的信息邓肯,我喜欢实践学习,发现你的答案非常有用。
SIOSocket.socketWithHost(server) { (socket: SIOSocket!) in
    self.socket = socket

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