我试图理解下面这个Ray Wenderlich tutorial的例子。我的主要困惑不在于什么(以方便的方式将JSON数据反序列化到您自己的对象中)它正在做什么,但 它在做什么它。我所做的就是解释我理解的代码片段,但我的困惑源于completionHandler闭包及其类型定义。在我最初接受代码所做的事之后,我会强调这一点。
首先是行号的代码段:
1 @objc public protocol ResponseObjectSerializable {
2 init(response: NSHTTPURLResponse, representation: AnyObject)
3 }
4
5 extension Alamofire.Request {
6 public func responseObject<T: ResponseObjectSerializable>(completionHandler: (NSURLRequest, NSHTTPURLResponse?, T?, NSError?) -> Void) -> Self {
7 let serializer: Serializer = { (request, response, data) in
8 let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
9 let (JSON: AnyObject?, serializationError) = JSONSerializer(request, response, data)
10 if response != nil && JSON != nil {
11 return (T(response: response!, representation: JSON!), nil)
12 } else {
13 return (nil, serializationError)
14 }
15 }
16
17 return response(serializer: serializer, completionHandler: { (request, response, object, error) in
18 completionHandler(request, response, object as? T, error)
19 })
20 }
21 }
第6行 - 这里我们声明一个接受&#34; completionHandler&#34;的通用函数(responseObject)。签名为(NSURLRequest, NSHTTPURLResponse?, T?, NSError?) -> Void
的封闭。然后它返回它自己的类-> self
的实例。
第7到第15行 - 这里我们使用Serializer
签名声明一个闭包。这样做可以将JSON转换为符合ResponseObjectSerializable协议的相应类。
17到19行 - 这里我们称之为&#34;响应()&#34; Alamofire.Request类中的方法(我认为?)传入先前定义的序列化器闭包。我们传入的是实际的 completionHandler闭包,然后调用其他一些神秘的completionHandler方法。这个&#34;响应()&#34;的结果方法调用返回给客户端代码。
我觉得我理解到&#34; completionHandler&#34;闭包在第17行作为参数传递。但是后来我们调用了其他一些&#34; completionHandler&#34; - 它在哪里定义?还是自称?
另外,当第7行创建的序列化程序看起来超出了第7行的范围时,我们如何引用它?
答案 0 :(得分:3)
如果您不理解,只需获取原始代码......
1 @objc public protocol ResponseObjectSerializable {
2 init(response: NSHTTPURLResponse, representation: AnyObject)
3 }
4
5 extension Alamofire.Request {
6 public func responseObject<T: ResponseObjectSerializable>(completionHandler: (NSURLRequest, NSHTTPURLResponse?, T?, NSError?) -> Void) -> Self {
7 let serializer: Serializer = { (request, response, data) in
8 let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
9 let (JSON: AnyObject?, serializationError) = JSONSerializer(request, response, data)
10 if response != nil && JSON != nil {
11 return (T(response: response!, representation: JSON!), nil)
12 } else {
13 return (nil, serializationError)
14 }
15 }
16
17 return response(serializer: serializer, completionHandler: { (request, response, object, error) in
18 completionHandler(request, response, object as? T, error)
19 })
20 }
21 }
...删除不相关的部分或像这样折叠它们......
5 extension Alamofire.Request {
6 public func responseObject<T: ResponseObjectSerializable>(completionHandler: (NSURLRequest, NSHTTPURLResponse?, T?, NSError?) -> Void) -> Self {
7 let serializer: Serializer = { ... }
16
17 return response(serializer: serializer, completionHandler: {
18 ...
19 })
20 }
21 }
...当你知道它正在做什么时,逐一展开折叠的部分。
那么,那里有什么......
第6行的 completionHandler
- public func responseObject<...
函数的第一个参数。它是一个闭包,你可以传递或使用它(执行它)。以下是Apple文档引用:
闭包是可以传递的自包含功能块 在您的代码中使用。 Swift中的闭包类似于块 在C和Objective-C以及其他编程语言中的lambda。
如果你想使用闭包(执行它),你可以使用它作为这样的函数:
completionHandler(pass arguments, to, this closure, here)
如果您想传递它,只需使用参数名称completionHandler
。
completionHandler
- func response
的第二个参数。在这里,我们通过第18行定义的功能(现在已折叠)传递闭包。此闭包可以在response
函数内使用,并通过参数名completionHandler
引用。但只有response
函数内部才有这个功能。那么,让我们扩展它......
5 extension Alamofire.Request {
6 public func responseObject<T: ResponseObjectSerializable>(completionHandler: (NSURLRequest, NSHTTPURLResponse?, T?, NSError?) -> Void) -> Self {
7 let serializer: Serializer = { ... }
16
17 return response(serializer: serializer, completionHandler: {
18 completionHandler(request, response, object as? T, error)
19 })
20 }
21 }
现在发生了什么......
在response
函数内部,我们传递的第17-19行的闭包可以传递或使用。
当它发生时,执行此闭包的主体(第18行)。
闭包体使用另一个闭包,它作为参数传递给函数responseObject
。
使其更短......当response
执行completionHandler
闭包(第17-19行)时,此闭包执行另一个闭包(第18行),该闭包作为参数传递给函数{{ 1}}(第6行)。
希望它能说清楚。这并不难,只是在分析代码时学习如何跳过代码的某些部分(在你的脑海中崩溃)。