无涯教程-Swift - 后台任务

81 阅读2分钟

在本教程的这一部分中,无涯教程将找到处理iOS应用程序中的后台任务的方法。在这里,无涯教程将改进在本教程前面各节中构建的应用程序之一,这是无涯教程创建的Artist Project,用于向用户显示Artist数据。

现在,无涯教程将使用多线程来改善Artist Project的性能。在Artist Project中,无涯教程已经在主线程的viewDidLoad()中执行了图像缓存。但是,这可以作为后台任务异步执行。在这里,无涯教程必须注意,所有UI更新任务都必须始终位于主线程上。

以下代码用于使用全局调度队列在后台执行图像缓存。

    DispatchQueue.global(qos: .background).async { [weak self] in
                    debugPrint("performing image caching")
                    guard let self = self else{
                        return
                    }
                    for i in result.results ?? []{
                            Alamofire.request(i.artworkUrl60!).responseImage 					                              {  (response) in
                            if response.result.value != nil{
                                let image = UIImage(data: response.data!, scale: 1.0)
                                self.imageCache.add(image!, withIdentifier: i.artworkUrl60! )
                       </span><span class="pun">}</span><span class="pln">
                    </span><span class="pun">}</span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
                </span><span class="typ">DispatchQueue</span><span class="pun">.</span><span class="pln">main</span><span class="pun">.</span><span class="pln">sync </span><span class="pun">{</span><span class="pln">
                    debugPrint</span><span class="pun">(</span><span class="str">"reloading tableview"</span><span class="pun">)</span><span class="pln">
                    </span><span class="kwd">self</span><span class="pun">.</span><span class="pln">tableView</span><span class="pun">.</span><span class="pln">reloadData</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
            
            </span><span class="pun">}</span></pre></div>

这将使viewDidLoad(:)在缓存图像并重新加载表格视图之前结束。在这里,无涯教程必须注意,表视图已在主线程上重新加载,并且所有UI更新都必须始终在主线程上进行。

修改后的ViewController.swift如下所示。

//
//  ViewController.swift
//  ParseJsonData
//
//  Created by Ayush Sharma on 06/08/19.
//  Copyright ? 2019 Apple Inc. All rights reserved.
//

import UIKit import Alamofire import AlamofireImage class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! var artist = Array() let imageCache = AutoPurgingImageCache(memoryCapacity: 111_111_111, preferredMemoryUsageAfterPurge: 90_000_000)

</span><span class="kwd">override</span><span class="pln"> func viewDidLoad</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">super</span><span class="pun">.</span><span class="pln">viewDidLoad</span><span class="pun">()</span><span class="pln">
   </span><span class="com">//Do any additional setup after loading the view.</span><span class="pln">
    loadJsonData</span><span class="pun">()</span><span class="pln">
    tableView</span><span class="pun">.</span><span class="kwd">delegate</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">self</span><span class="pln">
    tableView</span><span class="pun">.</span><span class="pln">dataSource </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">self</span><span class="pln">
    </span><span class="com">//tableView.rowHeight = UITableView.automaticDimension</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
func loadJsonData</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
   </span><span class="typ">Alamofire</span><span class="pun">.</span><span class="pln">request</span><span class="pun">(</span><span class="str">"https://itunes.apple.com/search?media=music&amp;term=bollywood"</span><span class="pun">).</span><span class="pln">responseJSON </span><span class="pun">{</span><span class="pln"> </span><span class="pun">(</span><span class="pln">response</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">in</span><span class="pln">
        </span><span class="com">//print("Response value \(response)")</span><span class="pln">
    </span><span class="kwd">do</span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">if</span><span class="pun">(</span><span class="pln">response</span><span class="pun">.</span><span class="pln">result</span><span class="pun">.</span><span class="pln">isSuccess</span><span class="pun">){</span><span class="pln">
            </span><span class="kwd">let</span><span class="pln"> result</span><span class="pun">:</span><span class="pln"> </span><span class="typ">ArtistResponseModel</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">try</span><span class="pln"> </span><span class="typ">JSONDecoder</span><span class="pun">().</span><span class="pln">decode</span><span class="pun">(</span><span class="typ">ArtistResponseModel</span><span class="pun">.</span><span class="kwd">self</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">from</span><span class="pun">:</span><span class="pln"> response</span><span class="pun">.</span><span class="pln">data</span><span class="pun">!)</span><span class="pln">
            debugPrint</span><span class="pun">(</span><span class="pln">result</span><span class="pun">)</span><span class="pln">
            </span><span class="kwd">self</span><span class="pun">.</span><span class="pln">artist </span><span class="pun">=</span><span class="pln"> result</span><span class="pun">.</span><span class="pln">results </span><span class="pun">??</span><span class="pln"> </span><span class="pun">[]</span><span class="pln">
            
            </span><span class="typ">DispatchQueue</span><span class="pun">.</span><span class="kwd">global</span><span class="pun">(</span><span class="pln">qos</span><span class="pun">:</span><span class="pln"> </span><span class="pun">.</span><span class="pln">background</span><span class="pun">).</span><span class="kwd">async</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">[</span><span class="pln">weak </span><span class="kwd">self</span><span class="pun">]</span><span class="pln"> </span><span class="kwd">in</span><span class="pln">
                debugPrint</span><span class="pun">(</span><span class="str">"performing image caching"</span><span class="pun">)</span><span class="pln">
                guard </span><span class="kwd">let</span><span class="pln"> </span><span class="kwd">self</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">self</span><span class="pln"> </span><span class="kwd">else</span><span class="pun">{</span><span class="pln">
                    </span><span class="kwd">return</span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
                </span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span class="pln"> result</span><span class="pun">.</span><span class="pln">results </span><span class="pun">??</span><span class="pln"> </span><span class="pun">[]{</span><span class="pln">
                        </span><span class="typ">Alamofire</span><span class="pun">.</span><span class="pln">request</span><span class="pun">(</span><span class="pln">i</span><span class="pun">.</span><span class="pln">artworkUrl60</span><span class="pun">!).</span><span class="pln">responseImage </span><span class="pun">{</span><span class="pln"> </span><span class="pun">(</span><span class="pln">response</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">in</span><span class="pln">
                        </span><span class="kwd">if</span><span class="pln"> response</span><span class="pun">.</span><span class="pln">result</span><span class="pun">.</span><span class="kwd">value</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="kwd">nil</span><span class="pun">{</span><span class="pln">
                            </span><span class="kwd">let</span><span class="pln"> image </span><span class="pun">=</span><span class="pln"> </span><span class="typ">UIImage</span><span class="pun">(</span><span class="pln">data</span><span class="pun">:</span><span class="pln"> response</span><span class="pun">.</span><span class="pln">data</span><span class="pun">!,</span><span class="pln"> scale</span><span class="pun">:</span><span class="pln"> </span><span class="lit">1.0</span><span class="pun">)</span><span class="pln">
                            </span><span class="kwd">self</span><span class="pun">.</span><span class="pln">imageCache</span><span class="pun">.</span><span class="kwd">add</span><span class="pun">(</span><span class="pln">image</span><span class="pun">!,</span><span class="pln"> withIdentifier</span><span class="pun">:</span><span class="pln"> i</span><span class="pun">.</span><span class="pln">artworkUrl60</span><span class="pun">!</span><span class="pln"> </span><span class="pun">)</span><span class="pln">
                                         
            </span><span class="pun">}</span><span class="pln">
                    </span><span class="pun">}</span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
                </span><span class="typ">DispatchQueue</span><span class="pun">.</span><span class="pln">main</span><span class="pun">.</span><span class="pln">sync </span><span class="pun">{</span><span class="pln">
                    debugPrint</span><span class="pun">(</span><span class="str">"reloading tableview"</span><span class="pun">)</span><span class="pln">
                    </span><span class="kwd">self</span><span class="pun">.</span><span class="pln">tableView</span><span class="pun">.</span><span class="pln">reloadData</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
            
            </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
        
    </span><span class="pun">}</span><span class="kwd">catch</span><span class="pun">{</span><span class="pln">
        
    </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
    debugPrint</span><span class="pun">(</span><span class="str">"end of view did load"</span><span class="pun">)</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

}

extension ViewController : UITableViewDataSource{ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return artist.count }

func tableView</span><span class="pun">(</span><span class="pln">_ tableView</span><span class="pun">:</span><span class="pln"> </span><span class="typ">UITableView</span><span class="pun">,</span><span class="pln"> cellForRowAt indexPath</span><span class="pun">:</span><span class="pln"> </span><span class="typ">IndexPath</span><span class="pun">)</span><span class="pln"> </span><span class="pun">-&gt;</span><span class="pln"> </span><span class="typ">UITableViewCell</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">let</span><span class="pln"> cell </span><span class="pun">=</span><span class="pln"> tableView</span><span class="pun">.</span><span class="pln">dequeueReusableCell</span><span class="pun">(</span><span class="pln">withIdentifier</span><span class="pun">:</span><span class="pln"> </span><span class="str">"MainTableViewCell"</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">as</span><span class="pun">!</span><span class="pln"> </span><span class="typ">MainTableViewCell</span><span class="pln">
    </span><span class="kwd">if</span><span class="pun">(</span><span class="pln">artist</span><span class="pun">.</span><span class="pln">count </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">0</span><span class="pun">){</span><span class="pln">
         </span><span class="kwd">let</span><span class="pln"> artistData </span><span class="pun">=</span><span class="pln"> artist</span><span class="pun">[</span><span class="pln">indexPath</span><span class="pun">.</span><span class="pln">row</span><span class="pun">]</span><span class="pln">
        </span><span class="typ">DispatchQueue</span><span class="pun">.</span><span class="pln">main</span><span class="pun">.</span><span class="kwd">async</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
            cell</span><span class="pun">.</span><span class="pln">artistImgView</span><span class="pun">.</span><span class="pln">image </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">self</span><span class="pun">.</span><span class="pln">imageCache</span><span class="pun">.</span><span class="pln">image</span><span class="pun">(</span><span class="pln">withIdentifier</span><span class="pun">:</span><span class="pln"> artistData</span><span class="pun">.</span><span class="pln">artworkUrl60</span><span class="pun">!)</span><span class="pln">
            
        </span><span class="pun">}</span><span class="pln">
            cell</span><span class="pun">.</span><span class="pln">trackName</span><span class="pun">.</span><span class="pln">text </span><span class="pun">=</span><span class="pln"> artistData</span><span class="pun">.</span><span class="pln">trackName
            cell</span><span class="pun">.</span><span class="pln">artisName</span><span class="pun">.</span><span class="pln">text </span><span class="pun">=</span><span class="pln"> artistData</span><span class="pun">.</span><span class="pln">artistName
            cell</span><span class="pun">.</span><span class="pln">artistCountry</span><span class="pun">.</span><span class="pln">text </span><span class="pun">=</span><span class="pln"> artistData</span><span class="pun">.</span><span class="pln">country


    </span><span class="pun">}</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> cell
    
</span><span class="pun">}</span><span class="pln">

} extension ViewController : UITableViewDelegate{ func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 220 }

}

由于无涯教程在代码中使用了打印语句,因此让无涯教程来看看下面给出的控制台输出。

"end of view did load"
ArtistProject.ArtistResponseModel
"performing image caching"
"reloading tableview"

参考链接

www.learnfk.com/ios/handlin…