如何从 Swift 的闭包中接收方法的输出?
Posted
技术标签:
【中文标题】如何从 Swift 的闭包中接收方法的输出?【英文标题】:How to receive an output for a method from a closure in Swift? 【发布时间】:2022-01-10 09:39:38 【问题描述】:如何接收 [TweetSentimentClassifierInput] 对象数组的输出以进一步发送到我的预测模型?
我有数组,但在一个闭包中,这使它无法作为方法输出返回。如果我在闭包之外初始化一个空数组,那么输出始终是一个空数组,因为 fetch 闭包需要时间才能完成。
代码
struct TweetFetcher
let tweetCount = 100
let swifter = Swifter(consumerKey: key, consumerSecret: secret)
func fetchTweets(with searchText: String) -> [TweetSentimentClassifierInput]
swifter.searchTweet(using: searchText, lang: "en", count: tweetCount, tweetMode: .extended) (results, searchMetadata) in
var tweets = [TweetSentimentClassifierInput]()
let data = results.description.data(using: .utf8)
do
let decodedData = try JSONDecoder().decode([TweetData].self, from: data!)
catch
print("Error with decoding, \(error)")
for tweet in decodedData
let tweetForClassification = TweetSentimentClassifierInput(text: tweet.full_text)
tweets.append(tweetForClassification)
failure: (error) in
print("Error with the Twitter API request, \(error)")
如何从闭包中返回一个非空数组作为方法输出?
【问题讨论】:
异步转换此方法,以 [TweetSentimentClassifierInput] 作为闭包参数传递闭包 您可以将自己的闭包/回调参数添加到 fetchTweets 并将其作为参数传递给该闭包,或者将属性添加到您在闭包中分配数组的结构 不相关,但您的代码无法编译。循环必须在do
范围内。
@vadian,谢谢。是的,你是对的。只是忘记移动它,这是强制尝试测试:)
【参考方案1】:
将此方法异步转换,以[TweetSentimentClassifierInput]
作为闭包参数传递闭包,并将错误作为辅助闭包参数,
func fetchTweets(with searchText: String, finished: ((_ sentiments: [TweetSentimentClassifierInput]?,_ error: Error?) -> Void))
swifter.searchTweet(using: searchText, lang: "en", count: tweetCount, tweetMode: .extended) (results, searchMetadata) in
var tweets = [TweetSentimentClassifierInput]()
let data = results.description.data(using: .utf8)
do
let decodedData = try JSONDecoder().decode([TweetData].self, from: data!)
catch
print("Error with decoding, \(error)")
for tweet in decodedData
let tweetForClassification = TweetSentimentClassifierInput(text: tweet.full_text)
tweets.append(tweetForClassification)
finished(tweets, nil)
failure: (error) in
print("Error with the Twitter API request, \(error)")
finished(nil, error)
【讨论】:
谢谢你,雷尼尔。但是如果我需要稍后在 ViewController 中调用 fetchTweets 怎么办?然后我应该给这个方法一个我在那个 VC 中没有的情感部分。现在我认为将我的 fetch 和 predict 方法结合起来可能会更容易,这样我就可以像在哪里完成(tweets,nil)一样传递数组......【参考方案2】:您应该使用completionHandler
概念来实现这样的异步操作:
struct TweetFetcher
let tweetCount = 100
let swifter = Swifter(consumerKey: key, consumerSecret: secret)
func fetchTweets(with searchText: String, completion: @escaping ([TweetSentimentClassifierInput]?, Error?) -> Void)
swifter.searchTweet(using: searchText, lang: "en", count: tweetCount, tweetMode: .extended) (results, searchMetadata) in
var tweets = [TweetSentimentClassifierInput]()
let data = results.description.data(using: .utf8)
do
let decodedData = try JSONDecoder().decode([TweetData].self, from: data!)
catch
print("Error with decoding, \(error)")
completion(nil, error)
for tweet in decodedData
let tweetForClassification = TweetSentimentClassifierInput(text: tweet.full_text)
tweets.append(tweetForClassification)
completion(tweets, nil)
failure: (error) in
print("Error with the Twitter API request, \(error)")
completion(nil, error)
用法
let fetcher = TweetFetcher()
fetcher.fetchTweets(with: "Keyword...") tweets, error in
if let error = error
print(error.localizedDescription)
else
// Use tweets array content here ...
【讨论】:
非常感谢!我在项目中进行了一些更改,成功实现了您的答案。我以前从未使用过 completionHandler 的概念(说实话,我只是 Swift 的新手)。你能推荐一些文章来更深入地理解这个概念吗? 不客气。实际上,完成处理程序是closures
的一种形式,所以我认为您应该知道闭包是如何工作的,以便更好地理解它。可以在 here 和 here 找到一个很好的完成处理程序教程以上是关于如何从 Swift 的闭包中接收方法的输出?的主要内容,如果未能解决你的问题,请参考以下文章