在关闭内部调用Swift Closure

我有以下代码:

twitterAPI?.verifyCredentialsWithUserSuccessBlock({ (userName, password) -> Void in twitterAPI?.getUserTimelineWithScreenName(userName, count: 100, successBlock: { ([AnyObject]!) -> Void in }, errorBlock: { (error :NSError!) -> Void in }) }, errorBlock: { (error :NSError!) -> Void in println("error block") }) 

我收到以下错误:

在此处输入图像描述

我尝试在外封闭内部说自己,但它没有用。 我错过了什么?

更新:仍有构建错误:

在此处输入图像描述

更新:如果我将getUserTimeline方法放在闭包之外,那么它可以工作。 这一个工作。

 // twitterAPI?.getUserTimelineWithScreenName("", successBlock: { (objects :[AnyObject]!) -> Void in // // }, errorBlock: { (error: NSError!) -> Void in // // }) 

但这不是:

 twitterAPI?.verifyCredentialsWithUserSuccessBlock({ (userName, password) -> Void in self.twitterAPI?.getUserTimelineWithScreenName("", successBlock: { (objects :[AnyObject]!) -> Void in }, errorBlock: { (error: NSError!) -> Void in }) }, errorBlock: { (error :NSError!) -> Void in }) 

更新:getUserTimeLine方法的定义

 self.twitterAPI?.getUserTimelineWithScreenName(, successBlock:  Void)!##([AnyObject]!) -> Void#>, errorBlock:  Void)!##(NSError!) -> Void#>) 

在此处输入图像描述

更新:现在,我收到一个构建错误,说错过了自己的参数。 我甚至没有使用那个构造函数。

  if let twitterAPI = self.twitterAPI { twitterAPI.verifyCredentialsWithUserSuccessBlock({ (userName, password) -> Void in twitterAPI.getUserTimelineWithScreenName(userName, successBlock: { (objects :[AnyObject]!) -> Void in }, errorBlock: { (error :NSError!) -> Void in }) }, errorBlock: { (error :NSError!) -> Void in }) } 

尝试:

  twitterAPI?.verifyCredentialsWithUserSuccessBlock({ (userName, password) -> Void in self.twitterAPI?.getUserTimelineWithScreenName(userName, successBlock: { (objects :[AnyObject]!) -> Void in }, errorBlock: { (error :NSError!) -> Void in }) return // <-- ADDED }, errorBlock: { (error :NSError!) -> Void in }) 

在这种情况下

 { (userName, password) -> Void in self.twitterAPI?.getUserTimelineWithScreenName("", successBlock: { (objects :[AnyObject]!) -> Void in }, errorBlock: { (error: NSError!) -> Void in }) } 

是一个“单表达式闭包”,它具有隐式非Void返回。

从Xcode 6.2 / Swift 1.1开始,您需要在此处显式return

或者,使用已修复此问题的Xcode 6.3 / Swift 1.2。

看到这个问题: 没有返回类型的单行闭包或Swift – ‘Bool’不是’Void’的子类型?

好的,通过你正在使用的方法名称,我猜你正在使用STTwitter库。 如果是这样的话,你会想要这样的东西:

  if let twitterAPI = self.twitterAPI { twitterAPI.verifyCredentialsWithSuccessBlock({ (String) -> Void in twitterAPI.getUserTimelineWithScreenName("test", successBlock: { (objects: [AnyObject]!) -> Void in println("success") }, errorBlock: { (error: NSError!) -> Void in println("failure") }) }, errorBlock: { (error: NSError!) -> Void in }) } 

在使用可选的self.twitterAPI变量之前,请注意let调用。

例如,简单版本。 但最好让monad

 twitterAPI?.verifyCredentialsWithUserSuccessBlock({[weak self] (userName, password) in self?.twitterAPI?.getUserTimelineWithScreenName(userName, count: 100, successBlock: {[weak self] (value: [AnyObject]!) in // success }) { (error: NSError!) in // error } }) { (error: NSError!) in // error } 

这是一个非常误导性的错误消息。 问题是内部变量不能是可选类型,所以你需要if/let它。

在操场上看看这个……

 class Foo:NSObject { func doThing(bug:Int,completion:((Void)->(Void))) { } } let woot = Foo() var bar:Foo? = Foo() bar?.doThing(7, completion: {}); woot.doThing(3, completion: { bar?.doThing(4, completion:{}); }); 

它没有编译和消息

无法转换表达式类型’(IntegerLiteralConvertible,completion :() – >() – $ T3)’来键入’()’

并不完全解决问题。

所以你解开了可选项

 woot.doThing(3, completion: { if let bar = bar { bar.doThing(4, completion:{}); } }); 

它现在编译。

而另一个问题

如果检查STTwitterAPI.h标头

 - (NSObject *)getUserTimelineWithScreenName:(NSString *)screenName successBlock:(void(^)(NSArray *statuses))successBlock errorBlock:(void(^)(NSError *error))errorBlock; 

只是方便了这个的完整签名。

 - (NSObject *)getUserTimelineWithScreenName:(NSString *)screenName sinceID:(NSString *)sinceID maxID:(NSString *)maxID count:(NSUInteger)count successBlock:(void(^)(NSArray *statuses))successBlock errorBlock:(void(^)(NSError *error))errorBlock; 

Obj-C to Swift桥接将所有内容放在括号内的第一个选择器块之后,因此方便的方法往往会因代码完成而混淆但不提供规范案例。

所以在你的情况下(没有我有STTwitter )这就是你想要的。

 twitterAPI?.verifyCredentialsWithUserSuccessBlock({ (userName, password) -> Void in if let twitterAPI = self.twitterAPI { twitterAPI.getUserTimelineWithScreenName("JohnSmith",sinceID:someID,maxID:anotherID,count:1000, successBlock: { (objects)[AnyObject]!) -> Void in }, errorBlock: { (error: NSError!) -> Void in }) } }, errorBlock: { (error :NSError!) -> Void in }) 

你如何选择填充sinceIDmaxIDcount取决于你。 我从来没有使用过API,因此不会猜测。 他们可能是无能为力的