2017-04-23 9 views
1

현재 고해상도 UIImages의 배열 2 개를 가지고 있으며 원래 해상도의 30 %로 축소하고 UITableView에 내용을 다시로드하려고합니다. viewWillAppear이 두 배열을 통해, 내가 루프라고UIImages 배열을 지정된 비율로 확장하면 UI가 몇 초 동안 응답하지 않게됩니까?

extension UIImage { 
    func resized(withPercentage percentage: CGFloat) -> UIImage? { 
     let canvasSize = CGSize(width: size.width * percentage, height: size.height * percentage) 
     UIGraphicsBeginImageContextWithOptions(canvasSize, false, scale) 
     defer { UIGraphicsEndImageContext() } 
     draw(in: CGRect(origin: .zero, size: canvasSize)) 
     return UIGraphicsGetImageFromCurrentImageContext() 
    } 
} 

, 30 % 아래로 배열의 각 이미지 크기를 조절 한 다음 테이블을 다시로드 : 나는 이미지를 축소하기 위해 레오 버스들이시길 answer에서 아래의 확장자를 사용하고 있습니다 viewWillAppear를 호출 할 때 잘 내 테이블 뷰로드

override func viewWillAppear(_ animated: Bool) 
{ 
    DispatchQueue.main.async { 

     for index in 0..<self.arrayOne.count 
     { 
      self.arrayOne[index].image = self.arrayOne[index].image?.resized(withPercentage: 0.3) 
     } 

     for index in 0..<self.arrayTwo.count 
     { 
      self.arrayTwo[index].image = self.arrayTwo[index].image?.resized(withPercentage: 0.3) 
     } 
    } 

    self.tableView.reloadData() 
} 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
{ 
    ... 

    let cellImage = cell.viewWithTag(1) as! UIImageView 

    var image: UIImage = UIImage() 

    if test1 == true 
    { 
     if let theImage = arrayOne[index].image 
     { 
      image = theImage 
     }   
    } 
    else 
    { 
     if let theImage = arrayTwo[index].image 
     { 
      image = theImage 
     } 
    } 

    cellImage.image = image 

    return cell 
} 

모든 데이터를하지만, 전체 UI 동결, 아무것도 터치에 반응하지 2 ~ 3 초 지연이있다 :과 같이 볼 수 있습니다. 지연 후, 응답이 다시 나타나고 정상입니다.

고해상도 이미지를 축소해야 할 때마다 무거운 작업을 수행하는 내 배율 기능과 관련이 있다고 확신합니다. UI가 일시적으로 반응하지 않게되지만이 문제를 해결하는 방법을 모르겠습니다. .

초기 UI가 응답하지 않는 문제를 어떻게 해결할 수 있습니까?

감사합니다.

+0

문제가 DispatchQueue.main.async와 연결되었습니다. –

+0

@OlegGordiichuk 대신 수행해야 할 작업은 무엇입니까? – Pangu

+1

백그라운드 스레드에서이 작업을 수행해야하며 모든 스케일링이 완료되면 메인 스레드에서 테이블 리로드 호출을 호출하십시오. –

답변

0

동결 이유는 메인 스레드가 UI 유지 관리에 사용되며 하드 계산을 실행하면 앱이 정지된다는 것입니다. 그래서 당신은 조각처럼 배경에 루프를 실행해야합니다 메인 스레드에서 UI 업데이트가 종료 후 :

DispatchQueue.global(qos: .background).async { 

    for index in 0..<self.arrayOne.count 
    { 
     self.arrayOne[index].image = self.arrayOne[index].image?.resized(withPercentage: 0.3) 
    } 

    for index in 0..<self.arrayTwo.count 
    { 
     self.arrayTwo[index].image = self.arrayTwo[index].image?.resized(withPercentage: 0.3) 
    } 

    DispatchQueue.main.async { 
     self.tableView.reloadData() 
    } 
} 

편집 : Here 다른 QoS를 설명.

+0

'DispatchQueue.global(). async'와'DispatchQueue.global (qos : .background) .async'의 차이점은 무엇입니까? – Pangu

+0

지정된 매개 변수가없는'DispatchQueue.global(). async'는 'default'qos에서 실행됩니다. apple에 따르면 "이 QoS의 우선 순위 수준은 사용자가 시작한 것과 유틸리티 사이입니다". 그로부터'DispatchQueue.global(). async'는'DispatchQueue.global (qos : .background) .async'보다 높은 우선 순위를가집니다. 더 자세한 정보는 https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/PrioritizeWorkWithQoS.html –

+0

@Pangu 질문에 대한 설명을 추가했습니다. – KostiaZzz