您不能定义匿名类,但可以定义一个工作方式非常相似的本地类。我实际上已经从内联类方法迁移了出来,因为 REPL 似乎有问题,即使编译器似乎没问题。我现在使用的方法是定义一个胶水类,它将方法转发到 init 中定义的闭包,所以感觉很自然。
URLConnectionDataDelegate 定义为:
class GreenUrlConnectionDataDelegate: NSObject, NSURLConnectionDataDelegate {
var didFinishLoading:()->()
var didReceiveResponse:((NSURLResponse!)->())?
var didReceiveData:((NSData!)->())?
var didFailWithError:((NSError!)->())?
func connectionDidFinishLoading(conn:NSURLConnection!) {
didFinishLoading()
}
func connection(conn:NSURLConnection!, didReceiveResponse response:NSURLResponse!) {
didReceiveResponse?(response)
}
func connection(conn:NSURLConnection!, didReceiveData data:NSData!) {
didReceiveData?(data)
}
func connection(conn:NSURLConnection!, didFailWithError error:NSError!) {
didFailWithError?(error)
}
init(
didFinishLoading:@escaping ()->(),
didReceiveResponse:@escaping ((NSURLResponse!)->())? = nil,
didReceiveData:@escaping ((NSData!)->())? = nil,
didFailWithError:@escaping ((NSError!)->())? = nil
) {
self.didFinishLoading = didFinishLoading
self.didReceiveResponse = didReceiveResponse
self.didReceiveData = didReceiveData
self.didFailWithError = didFailWithError
}
}
这允许我使用内联委托定义函数:
func downloadUrl(string:String, completion:(data:NSData?, error:NSError?) -> ()) {
let url = NSURL(string:string)
let request = NSURLRequest(URL: url)
var received:NSMutableData! = nil
let conn = NSURLConnection(request: request, delegate: GreenUrlConnectionDataDelegate(
didFinishLoading:{
completion(data:received, error:nil)
},
didReceiveResponse:{response in
if let capacity = response?.expectedContentLength {
if capacity > 0 {
received = NSMutableData(capacity: Int(capacity))
}
else {
received = NSMutableData()
}
}
},
didReceiveData:{data in
if data != nil {
received.appendData(data)
}
},
didFailWithError:{error in
completion(data:nil, error:error)
}
)
)
}
以及在操场上对其进行测试的代码:
downloadUrl("http://www.google.com") {
(data:NSData?, error:NSError?) -> () in
println("completion")
println("data.size: \(data?.length)")
println("error: \(error?.localizedDescription)")
}
XCPSetExecutionShouldContinueIndefinitely()
您甚至可以将粘合类嵌入到需要委托的类的扩展中,尽管我还没有尝试过。