2017-04-19 3 views
0

URLSession.shared.dataTask 작업 내에서 클로저를 호출합니다. 문제는 클로저 내부에 중단 점을 설정하면 실행이 완료되지 않는다는 것입니다.URLSession.shared.dataTask의 완료 핸들러 내 클로저

func query(url: String, args: [String:String], completion: @escaping (_ data: Data) -> Void) { 
// Create request url in order to query API. 
let url = makeGetRequestUsing(url: url, args: args) 
let task = URLSession.shared.dataTask(with: url!) { data, response, error in 
    guard let data = data, error == nil else { 
     print("error:", error ?? "") 
     return 
    } 
    completion(data) 
} 

task.resume() 

그리고 내가 이렇게 부릅니다.

self.comments = [] 
api.query(url: url, args: args) { data in 
    let jsonData = try! JSONSerialization.jsonObject(with: data) 
    print(String(data: data, encoding: .utf8)) 
    if let jsonArray = jsonData as? [[String: Any]] { 
     // Create comments from the json received. 
     for i in 0..<jsonArray.count { 
      do { 
       self.comments.append(try Comment(json: jsonArray[i])) 
      } catch { 
       print(error) 
      } 
     } 
     DispatchQueue.main.async { 
      self.refreshComments() 
     } 
    } 
} 

완료 처리기 안에 중단 점을 설정했으며 오류는 주석 클래스의 초기화에서 비롯된 것으로 보입니다.

init(json: [String: Any]) throws { 
// Get the comment text. 
guard let comment = json[Comment.commentText] as? String else { 
    throw SerializationError.missing(Comment.commentText) 
} 

// Get userImage. 
guard let userId = json[Comment.userId] as? Int, 
    let userImage = APIData.shared.getImage(url: "/userImageForId", args: ["id": String(userId)]) else { 
    throw SerializationError.missing(Comment.userId) 
} 

// Get userename. 
guard let resp = APIData.shared.getQuery(url: "/userNameForId", args: ["id": String(userId)]) as? [String: String], 
    let username = resp[Comment.username] else { 
    throw SerializationError.missing(Comment.username) 
} 

self.comment = comment 
self.username = username 
self.userImage = userImage 

}

는 getQuery 된 GetImage하고는 첫 번째 코드와 동일하다. 나는 작업을 시작하고 세마포어를 사용하여 결과를 얻을 때까지 기다린다.

+0

위의 코드를 수행 한 후에 아무 곳에서나 task.resume()을 호출하지 않습니다. –

+0

나는 그것을 여기에 포함시킬 필요가 없다고 생각했다. – user2232305

+1

jsonData는 사전이나 배열에 대해 오해의 소지가있는 이름입니다. –

답변

0

클로저가 실행을 완료하지 않았고 게시하지 않은 코드 어딘가에 세마포어를 사용하고 있다고 말한 것입니다. 세마포어를 잘못 사용하고 스레드를 차단하고있을 가능성이 큽니다.

처음에는 세마포어를 사용하는 영장을 볼 수있는 문제는 없습니다. 세마포 및 예외를 가져옴으로써 코드 방식을 필요한 것보다 더 복잡하게 만드는 것 같습니다.

단위 테스트 코드를 작성하고 논리를 한 번에 빌드하는 방법을 읽어 보시기 바랍니다. 이 시간에 씹을 수있는 것보다 더 많이 물어 뜯는 것처럼 보입니다.

관련 문제