在completionHandlers中存储值 - Swift

2024-05-14

我正在创建一个completionHandler它返回一个字典,但是当我在另一个类中调用这个方法时,它的值是零。

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 项目中的其他位置调用?


你的问题是乱码。您的示例代码无效,并且未显示正在使用的完成处理程序。

我怀疑您误解了异步请求和完成处理程序的工作原理。这是顺序。

  1. 调用函数并提供完成处理程序
  2. 函数立即返回,并在未来某个时刻运行请求
  3. 完成处理程序后的下一行在请求开始处理之前运行。您的应用程序继续运行。由于请求尚未完成,因此无可用结果。
  4. 异步请求终于完成。原始方法调用完成处理程序。现在,结果在完成处理程序的代码中可用。完成处理程序代码执行处理结果所需的任何操作。

下面是一个带有完成处理程序的异步进程如何工作的实际示例:(您可以在 Github 上找到一个演示此代码的工作 Xcode 项目:这个链接 https://github.com/DuncanMC/SwiftCompletionHandlers.git)

首先是一个 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__)")
  }
}

它是一个单例。它有一个静态的letsharedAsyncManager,您可以使用它来获取AsyncManager的单个实例。

AsyncManager 提供了一个方法 asyncFetchImage,它采用图像名称和完成块。该函数不返回任何结果,因为它在图像加载发生之前立即返回。

该代码并没有真正从互联网下载图像。相反,它只是使用 GCD 调用dispatch_after 在加载图像并调用完成块之前等待 3 秒。

现在我创建一个 ViewController 类并给它一个“加载图像”按钮。我创建一个IBOutlet theImageViewto a 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")
  }
}

现在,有趣的部分。以下是事件的顺序:

我按下加载图像按钮。 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 IBAction 的最后一行:

println("After call to asyncFetchImage")

在显示有关加载图像的消息之前显示一条消息。在完成任何工作之前,对 asyncFetchImage 的代码调用立即返回。接下来运行调用 asyncFetchImage 后的代码,但图像仍未加载。此时无法返回结果,因为图像加载尚未开始。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在completionHandlers中存储值 - Swift 的相关文章

随机推荐

  • knockoutjs通过点击事件获取元素id

    我正在使用 knockoutjs 目前我认为有些东西看起来像这样 img src images image1 png 这允许我获取视图模型中的元素 ID pressedTab function tab console log Element
  • 中心引导表宽度为 100%?

    table class table table striped table hover table responsive table
  • OpenSSL DH 密钥太小错误

    我正在尝试使用简单的 PERL 脚本连接到封闭的服务器 空调 usr bin perl use 5 10 1 use warnings use strict use IO Socket SSL use IO Socket SSL qw de
  • 二叉树中的 BFS

    我正在尝试编写二叉树中广度优先搜索的代码 我已将所有数据存储在队列中 但我不知道如何访问所有节点并消耗它们的所有子节点 这是我的 C 代码 void breadthFirstSearch btree bt queue q if bt NUL
  • 使用 Fullcalendar 和 Google 日历向过去的活动添加类

    我想更改过去事件的颜色 我想我需要向它们添加一个类 但这就是问题所在 我该怎么做 最好将类添加到事件对象的 className 属性中http arshaw com fullcalendar docs event data Event Ob
  • 如何使用 php 从字符串中提取日期

    我需要从字符串中提取日期 下面是我的代码和字符串 str Updated status to Masters Software Engineering Enrolled Documents to Send on 03 06 2014 14
  • 最好的开源帮助票系统是什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Python matplotlib:将轴标签/图例从粗体更改为常规粗细

    我正在尝试制作一些出版质量的图 但遇到了一个小问题 默认情况下 matplotlib 轴标签和图例条目的权重似乎比轴刻度线重 是否有办法强制轴标签 图例条目与刻度线的重量相同 import matplotlib pyplot as plt
  • 选择在 Excel 宏(VBA 中的范围对象)中具有值的列

    如何修改 VBA 中的这一行以仅选择具有值的列 Set rng Range A1 Range A65536 End xlUp SpecialCells xlCellTypeVisible 我不认为我做的事情是正确的CountLarge财产是
  • 安装 SQL Server 2012 错误“系统无法打开指定的设备或文件。”

    我正在尝试在已安装 SQL Server 2008 R2 Express 和 Windows 7 的计算机上安装 SQL Server 2012 Developer 我使用 Microsoft Secure Download Manager
  • 使用 fzf-tmux 进行快速窗口切换的 tmux 脚本给了我错误的选项

    我编写了以下内容 它允许我使用 fzf 切换 tmux 窗口 tmux list windows F I W fzf tmux cut d f 1 xargs tmux select window t 当我在 shell 中运行它时 它工作
  • 数组中连续元素的最大乘积

    我在现场面试的时候被问到了这个算法问题 由于没有要求我签署保密协议 我将其发布在这里寻求答案 给定一个数组REAL不包含 0 的数字 找到产生最大乘积的连续元素 该算法应在线性时间内运行 我考虑过以下方法 使用两个数组 第一个是利用DP思想
  • k8s书签解决什么问题?

    我正在尝试做什么 我正在尝试进行部署并监视 k8s 事件 直到部署准备好使用k8s节点API 手表 https github com kubernetes client javascript blob master examples typ
  • Python RE(总之检查第一个字母是否区分大小写,其余部分不区分大小写)

    在下面的情况下 我想匹配字符串 Singapore 其中 S 应始终为大写 其余单词可能为小写或大写 但在下面的字符串 s 是小写的 它在搜索条件中匹配 任何人都可以让我知道如何实施吗 import re st Information in
  • 从 R 到 C 处理列表并访问它

    我想使用从 R 获得的 C 列表 我意识到这个问题与此非常相似 使用 call 在 R 和 C 之间传递数据帧 https stackoverflow com questions 6658168 passing a data frame f
  • 使用 Apache 允许 Glassfish 和 PHP 在同一服务器中协同工作

    是否可以建立从 Java 到 php 文件的桥梁 我有一个用 Java 编写的应用程序 我需要执行http piwik org http piwik org 这是用 PHP 编写的 在服务器中 我正在运行 PHP 但无法从浏览器访问 php
  • IMAP 转发器

    我想知道从 IMAP 帐户转发邮件的最快 最可靠的方法是什么 我的大学不允许我们的学生邮箱转发到私人电子邮件帐户 这里每个人都使用 Gmail 或 Hotmail 这是一个政治问题 而不是技术问题 我们确实可以通过 IMAP 访问邮箱 我想
  • 如何从 PHP 中的字符串创建可能的字符串组合?

    如何从 PHP 中的字符串创建可能的字符串组合 Exp input abc output array 0 gt a 1 gt ab 2 gt abc 3 gt ac 4 gt acb 5 gt b 6 gt ba 7 gt bac 8 gt
  • Socket.io 与服务器离线连接

    如何检测服务器是否离线或由于其他原因无法连接 我的代码看起来像这样 this socket io connect connectionInfo reconnect false 它不会抛出任何错误 因此 try catch 子句不起作用 Us
  • 在completionHandlers中存储值 - Swift

    我正在创建一个completionHandler它返回一个字典 但是当我在另一个类中调用这个方法时 它的值是零 func fetchLatestPosts completionHandler responseDict NSDictionar