在本教程的这一部分中,无涯教程将找到处理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&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">-></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">></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"
参考链接