Swift - 在 ViewDidLoad 后至少 10 秒加载本地图像

Posted

技术标签:

【中文标题】Swift - 在 ViewDidLoad 后至少 10 秒加载本地图像【英文标题】:Swift - Local images load at least 10 seconds after the ViewDidLoad 【发布时间】:2015-02-03 21:43:28 【问题描述】:

我开始学习ios开发已经两个月了。我正在创建一个首先需要登录视图的应用程序。所以,

    我使用 HTTP get 方法 - 异步 - 检查登录信息并获取 Json 响应。 我开始理解使用委托/协议的方式。我认为我在委派方面做的一切都是正确的。 在我的 LoginViewController(1st) 中,我检查了从 GET 请求返回的数据。我的数据到了。 4.当一切正确时,我将用户数据保存到 UserDefaults 并执行 segue。

所以我的问题是; 加载 SecondViewController 时,应该在视图中看到的每个元素都在那里,除了愚蠢的图像(完全静态,没有以编程方式添加或编辑)。它们在视图加载完成后 10 或 20 秒加载。查询肯定完成了,因为第二个 VC 在加载后立即正确显示数据。

我注意到当我仅异步获取数据时会出现此问题。

我尝试了同步获取方法。视图一出现,图像就会加载。

我错过了什么?感谢您的任何想法。

这是我的代码:

class LoginViewController: UIViewController, UITextFieldDelegate, ConnectionDelegate 

var connectionModel:ConnectionModel = ConnectionModel()
var userDefaults:UserDefaults = UserDefaults()

@IBOutlet weak var codeField: UITextField!
@IBOutlet weak var usernameField: UITextField!
@IBOutlet weak var passwordField: UITextField!
@IBOutlet weak var failedLabel: UILabel!
@IBOutlet weak var rememberSwitch: UISwitch!
@IBOutlet weak var loading: UIActivityIndicatorView!


override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.connectionModel.delegate = self

    if(self.userDefaults.remember())
        self.loading.startAnimating()
        self.connectionModel.fetchBasicData()
    


func resultCame(value: Int) 
    self.loading.stopAnimating()

    switch value 
    case 1:
        loginToMain()
    case 2:
        noStudent()
    case 3:
        serverFailed()
    case 0:
        connectionFailed()
    default:
        connectionFailed()
    



override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.


@IBAction func loginButtonTapped(sender: UIButton) 
    self.loading.startAnimating()
    self.connectionModel.checkLogin(usernameField.text, password: passwordField.text, code:codeField.text)


func loginToMain()
    if(self.rememberSwitch.on)
        self.userDefaults.rememberUser()
    
    self.performSegueWithIdentifier("loginToMain", sender: self)


func noStudent()
    self.failedLabel.text = "Giriş bilgileri bulunamadı."


func serverFailed()
    let alertController = UIAlertController(title: "Sunucu Hatası", message: "Hata Kodu: 0x03", preferredStyle: .Alert)

    let OKAction = UIAlertAction(title: "Kapat", style: .Default)  (action) in
        self.connectionModel.checkConn(self)
    
    alertController.addAction(OKAction)

    self.presentViewController(alertController, animated: false, completion:nil)


func connectionFailed()
    let alertController = UIAlertController(title: "Bağlantı Hatası", message: "Hata Kodu: 0x00", preferredStyle: .Alert)

    let OKAction = UIAlertAction(title: "Kapat", style: .Default)  (action) in
        self.connectionModel.checkConn(self)
    
    alertController.addAction(OKAction)

    self.presentViewController(alertController, animated: falfalse, completion:nil)

编辑: 好的,我想我在尝试了 600 亿次不同的测试场景后现在想通了。图像未在第二个 VC 中加载;因为即使在我的数据从第一个 VC 中的异步请求到达并且结果执行 segue 之后,请求也没有在后台结束 20 秒。一旦请求完成(谁知道为什么),图像就会加载。

为什么即使在完成处理程序运行后请求仍然处于活动状态并保持连接?我没有任何意义!??

已解决: 没有人告诉我在完成处理程序中使用这个 f.ing 函数。显然,这就是图像加载这么晚的原因。呜呜呜……

dispatch_async(dispatch_get_main_queue()) 
    self.loading.stopAnimating()
    self.label.text = "string coming from data"

【问题讨论】:

很难说,因为我们可以看到似乎在 ConnectionModel 中的完成处理程序 谢谢汤姆。我刚刚了解到我必须在 comp 处理程序中使用 dispatch_async(dispatch_get_main_queue()) 。一段简单的代码让我头痛了 2 天。任何!我现在很好:) 【参考方案1】:

如果您的图片正在下载,那么当异步下载它们时,UI 的其余部分将加载,并且仅在完成下载后才会加载图片(因此时间取决于您的连接速度)。

但是,如果您的图片是同步下载的,那么应用程序将等到它们被下载后刷新 UI,这就是为什么所有内容都同时显示的原因。

【讨论】:

感谢您的回复,但我的图像不是远程图像。它们位于应用程序包内。 您在哪里调用要更新的图像?你能显示更多代码吗?我的猜测是调用是在您请求的完成处理程序中进行的,这就是它们不会显示的原因 好吧,在尝试了 600 亿个不同的测试场景之后,我想我现在想通了。图像未在第二个 VC 中加载;因为即使在我的数据从第一个 VC 中的异步请求到达并且结果执行 segue 之后,请求也没有在后台结束 20 秒。一旦请求完成(谁知道为什么),图像就会加载。为什么即使在完成处理程序运行后请求仍然处于活动状态和连接状态?我没有任何意义。

以上是关于Swift - 在 ViewDidLoad 后至少 10 秒加载本地图像的主要内容,如果未能解决你的问题,请参考以下文章

在 viewDidLoad Swift 3 中循环播放音频音乐的问题

获取数据后更新选项卡项徽章(Swift)

加载远程数据后 swift alamofire 显示视图控制器

Swift 单元测试 - 等待 viewDidLoad

ViewDidLoad 未按正确顺序执行操作 - Firebase、Swift

Swift 4:在 viewDidLoad 之后调用 prepare(for segue:)