从swift中的单独类访问label.text

SKY*_*ine 0 viewcontroller ios swift

我有一个带有按钮的viewController,允许用户从URL下载文件.为了保持我的代码清洁,我创建了一个从我的视图中调用的下载类.它工作正常但现在我想为用户提供有关下载的一些UI提示.

假设我有一个标签,我想在下载结束后将其文本更改为"已下载".应该怎么做?

这是我的代码:

FileViewController

@IBOutlet weak var downloadLbl: UILabel!

func downloadFile(sender:UIButton!)
    {      
        fileDownloader().download_zip(datastring, destination: path, name: naming, fileis: self.fileId)
    }
Run Code Online (Sandbox Code Playgroud)

(这只是重要的部分)

然后我将我的下载功能放在一个单独的类文件中,然后启动一个DownloadTaskSession并使用以下委托来观察下载完成

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
        println("session \(session) has finished the download task \(downloadTask) of URL \(location).")

        FileViewController().downloadLbl.text = "downloaded"
    }
Run Code Online (Sandbox Code Playgroud)

最后一行:FileViewController().downloadLbl.text = "downloaded"返回错误:致命错误:在展开Optional值时意外发现nil.

有人可以帮忙吗?

结论

这两个提议的解决方案在创建通信之间的通信时都有用,但是我去了通知解决方案,因为在我的情况下我必须更新UI以及后台线程进展并且使用协议不能按预期工作.进行了通信,但即使在使用dispatch_async方法推回主线程上的更改之后,更新UI仍无法正常工作.

使用通知系统有帮助,因为它更容易实现,管理和用于UI修改.

Aar*_*ger 8

在这段代码中:

FileViewController().downloadLbl.text = "downloaded"
Run Code Online (Sandbox Code Playgroud)

您正在创建一个新的FileViewController,而不是引用现有的.这个新标签还没有标签,因为它的视图尚未构建.你参考downloadLbl,这是一个UILabel!.它是nil,所以你的应用程序崩溃.

我有一个单独的类文件中的下载功能

这是一个很好的做法,但是让这个单独的类修改UI是一种不好的做法.相反,你应该编写一个定义这些类如何交互的Swift协议.

一个简单的例子:

protocol MyAwesomeDownloadResponder : class {
    func downloadFinished()
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在视图控制器中实现此方法:

class FileViewController : UIViewController, MyAwesomeDownloadResponder {
    @IBOutlet weak var downloadLbl: UILabel!

    func downloadFinished() {
        downloadLbl.text = "Downloaded"
    }
}
Run Code Online (Sandbox Code Playgroud)

在下载类中,存储一个引用responder,然后在下载完成时调用响应者:

class Downloader {
    weak var responder : MyAwesomeDownloadResponder?

    init(responder : MyAwesomeDownloadResponder) {
        self.responder = responder
    }

    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
        responder?.downloadFinished()
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您需要在这些类之间传递任何信息,请在中定义它protocol.