我正在创建一个completionHandler
返回Dictionary的,但是当我在另一个类中调用此方法时,其值为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
可以查看Dictionary 的值并基于该值显示数据。例如,
func parseDictionary() {
NetworkManager.sharedInstance.fetchLatestPosts(responseDict: NSDictionary)
if (responseDict != nil) {
println("Dictionary is not empty")
}
这里的问题是,当我调用fetchLatestPosts
函数时,我nil
在尝试调用字典时收到一个值。
简而言之,我的问题是如何为完成处理程序分配值并在Xcode项目中的其他位置调用它?
您的问题很乱。您的示例代码无效,并且没有显示正在使用的完成处理程序。
我怀疑您误解了异步请求和完成处理程序的工作方式。这是顺序。
这是一个具有完成处理程序的异步过程如何工作的实际示例:(您可以在
此链接
上找到一个工作的Xcode项目,该项目在Github上演示了此代码)
首先是一个AsyncManager类,它模拟从互联网下载图像:
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调用dispatch_after来等待3秒钟,然后加载图像并调用完成块。
现在,我创建一个ViewController类,并给它一个“加载图像”按钮。我创建了IBOutlet
theImageView
一个UIImageView
,以显示要加载的图像。
我为“加载图像”按钮编写了IBAction方法。这是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方法运行。
它获得了对异步下载管理器单例的引用。
它显示一条消息,然后调用theAsyncManager.asyncFetchImage。AsyncManager.asyncFetchImage方法在输入时显示一条消息,在3秒钟后排队调用以加载图像,显示“
leaving”消息, 然后在加载图像之前 返回。没有返回任何内容,因为图像加载代码尚未运行。
视图控制器的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 IBAction的最后一行:
println("After call to asyncFetchImage")
在显示有关加载图像的消息之前显示一条消息。在完成任何工作之前,对asyncFetchImage的代码调用将立即返回。调用asyncFetchImage之后的代码将继续运行,但该图像仍未加载。此时无法返回结果,因为图像加载尚未开始。
问题内容: 我在Utilities类中使用loadImage方法,并且在通过闭包返回图像时遇到了一些麻烦。基本上因为我的代码可能返回图像或错误,所以在调用该方法时将其分配给image属性是行不通的。 我在类的方法声明中使用的方法是否错误,还是应该以不同的方式调用该方法以预期潜在的不同结果?谢谢 问题答案: 将处理程序添加到您的 loadImage 函数中: 迅捷3 像这样调用func: 斯威夫特2
我的完成处理程序有问题。下面是一个带有完成处理程序的函数,位于一个实用程序文件中: 我在视图控制器中调用它 输出清楚地表明该函数在运行该块之前没有等待完成: 我如何解决这个问题?
我目前正在学习swift,几个小时以来我一直在试图理解一个错误。由于查询,我试图从php脚本中获取一个xml文件,我使用一个完成处理程序作为回调来获取这些查询的结果。 问题是我对这些技术感到不舒服,它说缺少论据。 下面是使用完成处理程序的函数: 这是我调用这个函数的一段代码: 这段代码显示有关调用连接的此错误: 我做错了什么?为什么它要两个参数? 非常感谢您的帮助。 埃尔巴托
我有一个在视图上执行动画的功能。我想为此函数实现一个完成处理程序,该处理程序将在动画完成后调用。 在ViewController中... 在HudView类中... 我尝试了很多方法,但找不到正确的语法: 传递非转义参数“myCompletionHandler”到函数,期望一个@转义闭包 无法将“Void”类型的值转换为预期的参数类型“((Bool) - 闭包:使用非转义参数“myCompleti
问题内容: 我想知道如何为在Swift 3中创建的函数创建完成处理程序。这就是我在更新到Swift 3之前就完成函数的方式: 但是现在我无法找出目前可行的最佳方法。 问题答案: 在Swift 3中,闭包中的函数参数标签不见了。 删除所有出现并添加 并使用它
我试图更准确地理解斯威夫特的“关闭”。 但是和太难理解了 我搜索了许多Swift帖子和官方文件,但我觉得这仍然不够。 这是官方文件的代码示例 听说使用< code>@escaping有两种方式和原因 第一个用于存储闭包,第二个用于异步操作目的。 以下是我的问题: 首先,如果执行,则将使用闭包参数执行,并且该闭包将保存在全局变量数组中。 我认为闭包是{self.x=100} {self.x=100}