簡體   English   中英

在關閉內部調用Swift Closure

[英]Calling Swift Closure Inside 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(<#screenName: String!#>, successBlock: <#(([AnyObject]!) -> Void)!##([AnyObject]!) -> Void#>, errorBlock: <#((NSError!) -> 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調用。

斯威夫特4

這是一個簡單的例子。 但最好通過monad實現。

...
guard let api = twitterAPI else { return }

api.verifyCredentialsWithUserSuccessBlock({ userName, password in
    api.getUserTimelineWithScreenName(
        userName, 
        count: 100, 
        successBlock: { value in
            // success
        }) { error in 
            print("get user error: \(error)") 
        }
}) { error in 
    print("verify error: \(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<STTwitterRequestProtocol> *)getUserTimelineWithScreenName:(NSString *)screenName
                                                         successBlock:(void(^)(NSArray *statuses))successBlock
                                                           errorBlock:(void(^)(NSError *error))errorBlock;

只是方便完全簽名。

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

Obj-C到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,因此不會猜測。 他們可能是無能為力的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM