Ответ 1
Вы не можете определить анонимный класс, но вы можете определить локальный класс, который работает очень похоже. Я на самом деле отошел от подхода встроенного класса, так как у 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:()->(),
didReceiveResponse:((NSURLResponse!)->())? = nil,
didReceiveData:((NSData!)->())? = nil,
didFailWithError:((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()
Вы могли бы даже встроить класс клея в расширение класса, требующего делегата, хотя я этого еще не пробовал.