【问题标题】:Swift - Variable lost dataSwift - 可变丢失数据
【发布时间】:2016-12-13 21:49:21
【问题描述】:

Xcode 8.1、Swift 2.3、iOS 10.1,我使用 Firebase

我不会在关闭之外访问数据。我想获取downloadURL1和downloadURL2,比如self.url1 = downloadURL1

但是 downloadURL1 在闭包之外是 nil 。

storageRef.child(filePath1).putData(data1, metadata: metaData) { (metadata1, error1) in
            if let error = error1 {
                print(error.localizedDescription)
                return
            } else {
                let downloadURL1 = metadata1!.downloadURL()!.absoluteString                
            }
        }

        storageRef.child(filePath2).putData(data2, metadata: metaData) { (metadata2, error2) in
            if let error = error2 {
                print(error.localizedDescription)
                return
            } else {
                let downloadURL2 = metadata2!.downloadURL()!.absoluteString
            }
        }

【问题讨论】:

  • 您在闭包中定义变量,当闭包结束时它们不再存在,并且它们在外部不可用......例如,您需要一个类变量

标签: swift firebase swift2.3


【解决方案1】:

你说:

downloadURL1nil 外部关闭。

是的,这是有道理的,因为这个闭包是异步运行的(即稍后)。您只能在闭包内使用它(或在闭包完成时启动的某些任务)。

例如,如果您只想在这两个下载都完成后才对它们进行某些操作,则使用将调度组:

var downloadURL1: String?
var downloadURL2: String?

let group = dispatch_group_create()

dispatch_group_enter(group)
storageRef.child(filePath1).putData(data1, metadata: metaData) { (metadata1, error1) in
    defer { dispatch_group_leave(group) }

    if let error = error1 {
        print(error.localizedDescription)
        return
    } else {
        downloadURL1 = metadata1!.downloadURL()!.absoluteString                
    }
}

dispatch_group_enter(group)
storageRef.child(filePath2).putData(data2, metadata: metaData) { (metadata2, error2) in
    defer { dispatch_group_leave(group) }

    if let error = error2 {
        print(error.localizedDescription)
        return
    } else {
        downloadURL2 = metadata2!.downloadURL()!.absoluteString
    }
}

dispatch_group_notify(group, dispatch_get_main_queue()) {
    // you use `downloadURL1` and `downloadURL2` here
}

// but not here

【讨论】:

    【解决方案2】:

    如果我猜对了,你是说不能在闭包之外下载 URL1 和 downloadURL2 的值?

    好吧,如果是这样,那是完全正常的。您应该在之前在闭包之外声明您的变量。但是尝试在闭包之外使用这两个变量的值是行不通的,因为它是异步的。

    因此您可能还想使用它们的 didSet 属性。但是在这种情况下,为什么要使用 downloadURL1 和 downloadURL2 而不是直接做类似的事情呢?

        var url1: String? {
            didSet {
                // Do whatever you want, like call a function, once url1 is set
            }
        }
        var url2: String? {
            didSet {
                // Do whatever you want, like call a function, once url2 is set
            }
        }
    
        storageRef.child(filePath1).putData(data1, metadata: metaData) { (metadata1, error1) in
            if let error = error1 {
                print(error.localizedDescription)
                return
            } else if let downloadURL1 = metadata1?.downloadURL()?.absoluteString {
              // Just to make sure it isn't nil
                self.url1 = downloadURL1                
            }
        }
    
        storageRef.child(filePath2).putData(data2, metadata: metaData) { (metadata2, error2) in
            if let error = error2 {
                print(error.localizedDescription)
                return
            } else if let downloadURL2 = metadata2?.downloadURL()?.absoluteString {
                self.url2 = downloadURL2               
            }
        }
    

    但也许我根本不明白你的问题?

    编辑:我假设您在 viewController 或某种类中使用所有这些

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-03
      • 2017-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-29
      相关资源
      最近更新 更多