在completionHandlers中存储值-Swift
我正在创建一个在completionHandlers中存储值-Swift,swift,Swift,我正在创建一个completionHandler,它返回一个字典,但是当我在另一个类中调用这个方法时,它的值是nil func fetchLatestPosts(completionHandler: (responseDict: NSDictionary) -> Void in { // Bunch of JSON Parsing for dictionary to be completed var theDictionary = JSON Dictionary value respons
completionHandler
,它返回一个字典,但是当我在另一个类中调用这个方法时,它的值是nil
func fetchLatestPosts(completionHandler: (responseDict: NSDictionary) -> Void in {
// Bunch of JSON Parsing for dictionary to be completed
var theDictionary = JSON Dictionary value
responseDict = theDictionary as NSDictionary
}
然后我尝试在另一个类中调用它,以便可以查看fetchLatestPost
字典中的值,并基于该值显示数据。
比如说,
func parseDictionary() {
NetworkManager.sharedInstance.fetchLatestPosts(responseDict: NSDictionary)
if (responseDict != nil) {
println("Dictionary is not empty")
}
这里的问题是,当我调用fetchLatestPosts
函数时,我在尝试调用字典时收到一个nil
值
简言之,我的问题是如何将值分配给存储在Xcode项目中并可以在其他地方调用的完成处理程序。您的示例代码无效,并且未显示正在使用的完成处理程序 我怀疑您误解了异步请求和完成处理程序的工作方式。下面是顺序
class AsyncManager
{
static let sharedAsyncManager = AsyncManager()
func asyncFetchImage(#imageName: String, completion: (image: UIImage?, status: String) -> ())
{
println("Entering \(__FUNCTION__)")
//Simulate a network operation by waiting 3 seconds before loading an image
let nSecDispatchTime = dispatch_time(DISPATCH_TIME_NOW,
Int64(3.0 * Double(NSEC_PER_SEC)))
let queue = dispatch_get_main_queue()
dispatch_after(nSecDispatchTime, queue)
{
() -> Void in
let result = UIImage(named: imageName)
println("Loading image in background")
let status = result != nil ? "image loaded" : "Error loading image"
println("About to call completion handler")
completion(image: result, status: status)
}
println("Leaving \(__FUNCTION__)")
}
}
这是一个单身汉。它有一个静态let sharedAsyncManager,您可以使用它获取AsyncManager的单个实例
AsyncManager提供一个方法asyncFetchImage,该方法采用图像名称和完成块。函数不会返回任何结果,因为它会在图像加载发生之前立即返回
代码并没有真正从互联网下载图像。相反,它只是使用GCD call dispatch_after在加载映像和调用完成块之前等待3秒钟
现在我创建了一个ViewController类,并给它一个“加载图像”按钮。我创建了一个IBOutlet
图像视图
到一个ui图像视图
,它将显示我要加载的图像
我为Load Image按钮编写了一个iAction方法。以下是IBAction的外观:
@IBAction func loadImage(sender: UIButton)
{
let theAsyncManager = AsyncManager.sharedAsyncManager
println("about to call asyncFetchImage")
theAsyncManager.asyncFetchImage(imageName: "wareto_blue_150x115")
{
(image, status) -> () in
println("Beginning completion block")
self.theImageView.image = image
println("In completion block, status = \(status)")
}
println("After call to asyncFetchImage")
}
}
现在,有趣的部分。以下是事件的顺序:
我按下loadImage按钮。IBAction方法运行
它获取对异步下载管理器单例的引用
它显示一条消息,然后调用AsyncManager.asyncFetchImage。AsyncManager.asyncFetchImage方法在输入时显示一条消息,在3秒钟后排队调用以加载图像,显示一条“离开”消息,并在加载图像之前返回。没有要返回的内容,因为图像加载代码尚未运行
视图控制器的loadImage方法显示“调用asyncFetchImage后”消息并返回
几秒钟后,asyncFetchImage中的代码实际运行。它显示一条消息,加载图像,然后调用完成处理程序
以下是运行上述代码时返回的消息集:
about to call asyncFetchImage
Entering asyncFetchImage(imageName:completion:)
Leaving asyncFetchImage(imageName:completion:)
After call to asyncFetchImage
Loading image in background
About to call completion handler
Beginning completion block
In completion block, status = image loaded
请注意,loadImage iAction的最后一行:
println("After call to asyncFetchImage")
在显示有关加载图像的消息之前显示消息。对asyncFetchImage的代码调用在任何工作完成之前立即返回。接下来将运行调用asyncFetchImage后的代码,但尚未加载映像。此时无法返回结果,因为图像加载尚未开始。您仍然不了解完成块是如何工作的。很可能是的,我是编程新手。抱歉。请参阅我的编辑。我添加了一个工作示例中的代码,显示了完成处理程序的实际工作方式。@Jack,我在Github上创建了一个名为的演示项目,演示了完成处理程序的工作方式。“我的编辑”中的代码取自该项目。我建议你下载并运行它。如果你不了解控制流是如何工作的,就添加断点。嘿,邓肯,我真的很感谢你发给我的演示项目,它帮助我理解了我想问的问题。我最初的问题是关于完成处理程序在异步调用期间存储值的部分,在您的示例中,该部分是将
result
和status
的值设置为image
和status
完成(image:result,status:status)。我现在明白了,非常感谢你的帮助!