2017-02-15 1 views
0

저는 스위프트를 iOS 개발자로 사용하고 있으며 최근에는 비동기 방식으로 하위보기를 추가하고 있습니다. dispatch_async (dispatch_get_main_queue())를 사용하고 있습니다. 서브 뷰는 하나씩 추가하지 않고 실시간으로 호출되지만 UI가 업데이트 될 때까지 기다려야합니다. 내 목표는 for 루프가 하나씩 차례대로 서브 뷰를 추가하고 실시간으로 추가하는 것입니다. 여전히 것. 다음은 내 코드의 일부이다. 누군가가 정말 감사하겠습니다 나를 도울 수 있다면.보기가 비동기로 하위보기를 추가하지 않습니다. Swift

for i in 0 ..< self.allChannels.count { 
     let param = Params().getEpgParams(String(self.allChannels[i].channelNumber))  
     uNetwork().httpRequestNoLoading(self.utilityClass.currentServer , parameters: param, method: uNetwork.METHOD.POST, parent: self) { (epgResponse, extra_information) ->() in 

      if(extra_information != uNetwork.EXTRA_INFORMATION.SUCCESS){ 
       self.presentViewController(self.utilityClass.alert("Error", message: "An Unexpected Error Happened"), animated: true, completion: nil) 
      } else if(epgResponse == nil){ 
       self.presentViewController(self.utilityClass.alert("Error", message: "Couldn't get any response from the server"), animated: true, completion: nil) 
      } else { 
       do { 
        var titleArray = [String]() 
        var start = [String]() 
        var end = [String]() 
        var progressArray = [Float]() 

        let jsonObject = try NSJSONSerialization.JSONObjectWithData(epgResponse, options: []) as! NSDictionary 
        if let response_object = jsonObject["response_object"] as? [[String: AnyObject]] { 
         for menu in response_object{ 
          titleArray.append(menu["title"] as! String) 
          start.append(menu["programstart"] as! String) 
          end.append(menu["programend"] as! String) 
          progressArray.append(menu["progress"] as! Float) 
         } 



         if(titleArray.count > 0){ 
          currentTitle = titleArray[0] 
          currentStart = start[0][start[0].startIndex.advancedBy(12)..<start[0].startIndex.advancedBy(12+4)] 
          currentEnd = end[0][end[0].startIndex.advancedBy(12)..<end[0].startIndex.advancedBy(12+4)] 
          progressValue = Float(progressArray[0]/100) 
         } else { 
          currentTitle = "Programet e \(self.allChannels[i].title)" 
          currentStart = "00:00" 
          currentEnd = "00:00" 
          progressValue = 0.5 
         } 

          dispatch_async(dispatch_get_main_queue(), { 
          indiSub[i].removeFromSuperview() 

          self.contentView = UIView(frame: CGRectMake(0, ((self.scrollView.frame.height/4) * CGFloat(i)), self.epgView.frame.width, self.scrollView.frame.height/4)) 
          self.contentView.layer.masksToBounds = true 
          self.scrollView.addSubview(self.contentView) 

          let button = UIButton(frame: CGRectMake(0, ((self.scrollView.frame.height/4) * CGFloat(i)), self.epgView.frame.width, self.scrollView.frame.height/4)) 
          button.tag = Int(self.allChannels[i].channelNumber) 
          button.addTarget(self, action: #selector(LiveTvTest.playFromEpg(_:)), forControlEvents: .TouchUpInside) 
          self.scrollView.addSubview(button) 

          let currentTime = UILabel(frame: CGRectMake((self.scrollView.frame.height/4) + 25, 0, 60, self.contentView.frame.height/3)) 
          if currentStart.characters.count == 4{ 
           currentTime.text = currentStart + "  |" 
          } else if (currentStart.characters.count == 5){ 
           currentTime.text = currentStart + " |" 
          } 
          currentTime.font = UIFont(name: "Helvetica Neue", size: 15) 
          currentTime.adjustsFontSizeToFitWidth = true 
          currentTime.textColor = UIColor(red:0.54, green:0.13, blue:0.13, alpha:1.0) 
          self.contentView.addSubview(currentTime) 

          let nextTime = UILabel(frame: CGRectMake((self.scrollView.frame.height/4) + 25, currentTime.frame.height, 60, self.contentView.frame.height/3)) 
          if nextStart.characters.count == 4{ 
           nextTime.text = nextStart + "  |" 
          } else if (nextStart.characters.count == 5) { 
           nextTime.text = nextStart + " |" 
          } 
          nextTime.font = UIFont(name: "Helvetica Neue", size: 15) 
          nextTime.adjustsFontSizeToFitWidth = true 
          nextTime.textColor = UIColor(red:0.53, green:0.53, blue:0.53, alpha:1.0) 
          self.contentView.addSubview(nextTime) 
          }) 


        } else { 
         print("something went wrong with response object") 
        } 




       } catch { 
        self.presentViewController(self.utilityClass.alert("Error", message: "Something went wrong, please try again later"), animated: true, completion: nil) 
       } 
      } 
     } 
    } 

답변

0

당신이 당신의 폐쇄 (당신이 httpRequestNoLoading에 손 있음) runni 있는지 확인 할 수있는 경우 임의의 스레드에서 실행하면 dispatch_sync UI 업데이트를 주 스레드로 사용할 수 있습니다. 작업 항목이 실행될 때까지 대기합니다. 그러나이 닫기가 이미 주 스레드에서 실행 중이면 확실히 교착 상태가됩니다.

btw. presentViewController 호출을 주 스레드로 보내야합니다.

0

나는 http 호출 집합을 설정한다는 것이 문제라고 생각합니다. 이러한 호출은 병렬로 실행되고 콜백을 통해 반환됩니다. 여러 뷰 업데이트를 매우 밀접하게 함께 수행하므로 코드가 연속적이더라도 업데이트가 빠르게 연속적으로 발생합니다.

다른 말로하면, osx/ios가 ui 업데이트를 배치한다는 것입니다. 한 번에 mainQueue에서 꽤 많은 작업을하고 있고, 작업을 볼 수있는 기회를 얻지 못할 수도 있습니다. dispatch_after을 사용하여 임의의 지연을 추가하여 다른 시간대에 상황이 나타나는지 확인해보십시오.

관련 문제