gpt4 book ai didi

swift - 在完成处理程序中存储值 - Swift

转载 作者:搜寻专家 更新时间:2023-10-30 23:02:18 24 4
gpt4 key购买 nike

我正在创建一个返回字典的 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 函数时,我在尝试调用 Dictionary 时收到了一个 nil 值。

简而言之,我的问题是如何为完成处理程序分配值并存储并可以在 Xcode 项目中的其他地方调用?

最佳答案

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

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

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

这是一个带有完成处理程序的异步过程如何工作的真实示例:(您可以在 Github 上找到一个演示此代码的工作 Xcode 项目 this link)

首先是模拟从 Internet 下载图像的 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,它接受一个图像名称和一个完成 block 。该函数不返回任何结果,因为它会在图像加载发生之前立即返回。

代码并没有真正从互联网上下载图像。相反,它只是使用 GCD 调用 dispatch_after 在加载图像和调用完成 block 之前等待 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")
}
}

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

我按下加载图像按钮。 IBAction 方法运行。

它获取对异步下载管理器单例的引用。

它显示一条消息,然后调用 AsyncManager.asyncFetchImage。 AsyncManager.asyncFetchImage 方法在进入时显示一条消息,在 3 秒后排队调用以加载图像,显示“离开”消息,然后返回,在图像加载之前。没有什么可返回的,因为图片加载代码还没有运行。

View Controller 的 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 之后的代码,但图像仍未加载。此时无法返回结果,因为图像加载还没有开始。

关于swift - 在完成处理程序中存储值 - Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30235082/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com