了解 Alamofire 的响应对象序列化闭包的使用
Understanding Alamofire's Response Object Serialization use of Closures
我正在尝试理解取自此 Ray Wenderlich tutorial 的以下示例。我的主要困惑不在于 what(以一种方便的方式将 JSON 数据反序列化到您自己的对象中)它在做什么,而是 how它正在做。我要做的是按我的理解解释代码片段,但我的困惑源于 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 行 - 在这里我们声明了一个通用函数 (responseObject),它接受一个带有 (NSURLRequest, NSHTTPURLResponse?, T?, NSError?) -> Void
签名的 "completionHandler" 闭包。然后它 returns 它自己的一个实例 class -> self
.
第 7 到 15 行 - 这里我们使用 Serializer
签名声明一个闭包。这确实将 JSON 转换为符合 ResponseObjectSerializable 协议的适当 class 的实际工作。
第 17 到 19 行 - 这里我们在 Alamofire.Request class(我想?)中调用 "response()" 方法,传入先前定义的序列化器闭包。我们还传入的是一个 actual completionHandler 闭包,然后调用其他一些神秘的 completionHandler 方法。此 "response()" 方法调用的结果返回给客户端代码。
我觉得我理解到 "completionHandler" 闭包在第 17 行作为参数传递的地步。但是然后我们调用其他一些 "completionHandler" - 它在哪里定义?还是它在调用自己?
此外,当第 7 行的序列化器看似超出范围创建时,我们如何引用第 17 行的序列化程序?
不懂就拿你的原码...
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 }
...当你知道它在做什么时,将折叠的部分一个接一个地展开。
那么,那里有什么......
completionHandler
第 6 行 - public func responseObject<...
函数的第一个参数。这是一个闭包,您可以传递它或使用它(执行它)。这是 Apple 文档引用:
Closures are self-contained blocks of functionality that can be passed
around and used in your code. Closures in Swift are similar to blocks
in C and Objective-C and to lambdas in other programming languages.
如果你确实想使用闭包(执行它),你可以像这样将它用作函数:
completionHandler(pass arguments, to, this closure, here)
如果你想传递它,只需使用参数名称 completionHandler
.
completionHandler
第 17 行 - 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行),它作为参数传递给函数responseObject...
(第 6 行)。
希望它能说清楚。没那么难,只要学会在分析代码的时候跳过部分代码就可以了(脑子里折叠起来)。
我正在尝试理解取自此 Ray Wenderlich tutorial 的以下示例。我的主要困惑不在于 what(以一种方便的方式将 JSON 数据反序列化到您自己的对象中)它在做什么,而是 how它正在做。我要做的是按我的理解解释代码片段,但我的困惑源于 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 行 - 在这里我们声明了一个通用函数 (responseObject),它接受一个带有 (NSURLRequest, NSHTTPURLResponse?, T?, NSError?) -> Void
签名的 "completionHandler" 闭包。然后它 returns 它自己的一个实例 class -> self
.
第 7 到 15 行 - 这里我们使用 Serializer
签名声明一个闭包。这确实将 JSON 转换为符合 ResponseObjectSerializable 协议的适当 class 的实际工作。
第 17 到 19 行 - 这里我们在 Alamofire.Request class(我想?)中调用 "response()" 方法,传入先前定义的序列化器闭包。我们还传入的是一个 actual completionHandler 闭包,然后调用其他一些神秘的 completionHandler 方法。此 "response()" 方法调用的结果返回给客户端代码。
我觉得我理解到 "completionHandler" 闭包在第 17 行作为参数传递的地步。但是然后我们调用其他一些 "completionHandler" - 它在哪里定义?还是它在调用自己?
此外,当第 7 行的序列化器看似超出范围创建时,我们如何引用第 17 行的序列化程序?
不懂就拿你的原码...
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 }
...当你知道它在做什么时,将折叠的部分一个接一个地展开。
那么,那里有什么......
completionHandler
第 6 行 - public func responseObject<...
函数的第一个参数。这是一个闭包,您可以传递它或使用它(执行它)。这是 Apple 文档引用:
Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages.
如果你确实想使用闭包(执行它),你可以像这样将它用作函数:
completionHandler(pass arguments, to, this closure, here)
如果你想传递它,只需使用参数名称 completionHandler
.
completionHandler
第 17 行 - 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行),它作为参数传递给函数responseObject...
(第 6 行)。
希望它能说清楚。没那么难,只要学会在分析代码的时候跳过部分代码就可以了(脑子里折叠起来)。