2016-07-07 7 views
3

새로운 프로그래머임이 있으며 매우 분실했습니다.클로저와 완료 핸들이 혼동 스럽습니다.

저는 온라인 iOS 개발자 과정을 수강 중이며 콜렉션 뷰 셀을 구성하고있었습니다. 그러나 클로저 및 완료 핸들이 사용되었으며 이전에는 언급되지 않았습니다.

import UIKit 

class PersonCell: UICollectionViewCell { 

@IBOutlet weak var img: UIImageView! 

func configureCell(imgUrl: String) { 
    if let url = NSURL(string: imgUrl) { 
     downloadImg(url) 
    }   
} 

func downloadImg(url: NSURL) { 
    getDataFromURL(url) { (data, response, error) in 
     dispatch_async(dispatch_get_main_queue()) {() -> Void in 
      guard let data = data where error == nil else {return} 
      self.img.image = UIImage(data: data) 
     } 
    } 
} 

func getDataFromURL(url: NSURL, completion: ((data: NSData?, response: NSURLResponse?, error: NSError?) -> Void)) { 

    NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in 
     completion(data: data, response: response, error: error) 
    } .resume() 

} 
} 

"getDataFromURL"함수 다음에 완료 핸들러가 수행중인 작업을 설명 할 수 있습니까? 또한 클로저는 무엇을하고 있습니까? "(데이터, 응답, 오류)"가 전달됩니까? 신속하게 "데이터"는 "(데이터, 응답, 오류)"에서 NSData 등으로 가정됩니까? ?!은 "dataTaskWithURL"할 (이후 폐쇄 무엇 그것이 완료 핸들러 "

가 감사를 설정하는 것입니다

+0

설명서를 읽으면 https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html에 도움이됩니다. – kye

답변

2

좋은 질문입니다! closure은 변수처럼 취급하여 함수처럼 실행할 수있는 코드 모음 (일명 블록)입니다. 변수 이름으로 클로저를 참조 할 수 있으며, ■ 다른 변수와 마찬가지로 함수 호출에서 매개 변수로 닫히고 적절한 경우 코드를 실행합니다. 클로저는 코드에서 사용할 특정 매개 변수를 허용 할 수 있으며 반환 값을 포함 할 수 있습니다.

예 :

이 매개 변수로 두 개의 문자열을 받아 문자열을 반환하는 클로저입니다.

let closure: (String, String) -> String = { (a: String, b: String) -> String in 
               return a + b 
              } 

따라서, 다음은 "안녕하세요 잭!"를 출력 할 것이다 :

print(closure("Hello ", "Jack!")) 

클로저는 변수 유형이이 ("hello"String1 단지 같은 Int입니다). 변수 유형은 클로저가 수락하는 매개 변수와 클로저가 반환하는 값을 기반으로합니다. 따라서 위의 클로저는 두 문자열을 매개 변수로 받아 문자열을 반환하기 때문에 변수 유형은 (String, String) -> String입니다. 참고 : 아무 것도 반환되지 않으면 (즉, 반환 유형이 Void 인 경우) 반환 유형을 생략 할 수 있습니다 ((Int, String) -> Void(Int, String)과 동일 함).

completion handler은 특정 기능에 전달할 수있는 클로저입니다. 함수가 완료되면 종료를 실행합니다 (예 : 화면에서 애니메이션 효과가 끝나거나 파일 다운로드가 완료된 시점 등).

예 :

"완료!" 보기 컨트롤러가 표시를 마치면 인쇄됩니다. getDataFromURL 기능에 대한

let newClosure:() -> Void = {() -> Void in 
    print("Done!") 
} 
let someViewController = UIViewController(nibName: nil, bundle: nil) 
self.presentViewController(someViewController, animated: true, completion: newClosure) 

하자의 초점은 먼저 썼다. 변수는 NSData이고 닫는 변수는 (NSData?, NSURLResponse?, NSError?) -> Void입니다.따라서 클로저 (completion)는 NSData?, NSURLResponse?NSError? 유형의 세 가지 매개 변수를 사용하며 함수 선언에서 클로저를 정의한 방법이므로 아무 것도 반환하지 않습니다.

그런 다음 getDataFromURL으로 전화하십시오. documentation을 읽으면 두 번째 매개 변수로이 함수에 전달한 클로저가로드 작업이 완료 될 때 실행된다는 것을 알 수 있습니다. dataTaskWithURL의 함수 선언은 클로저가 수락하고 반환하는 변수 형식을 정의합니다. 이 클로저 내에서 getDataFromURL 함수로 전달한 클로저를 호출합니다.

downloadImg에 전화를 걸 때 정의한이 마감 시간 내에 다운로드 한 데이터가 nil이 아닌지 확인하고 그렇지 않은 경우 데이터를 이미지로 설정합니다 UIImageViewdispatch_async(dispatch_get_main_queue(), ...) 호출은 Apple의 사양에 따라 새 스레드를 주 스레드에 설정한다는 것을 보증합니다 (다른 스레드에 대한 자세한 정보는 해당 위치에서 읽을 수 있습니다).

0

이것을 이해하는 typealias을하는 것은 쉽다 :이 있습니다

typealias Handle = (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void 
//the func should be 
func getDataFromURL(url: NSURL, completion: Handle) 
//when you call it. it needs an url and an Handle 
getDataFromURL(url:NSURL, completion: Handle) 
// so we pass the url and handle to it 
getDataFromURL(url) { (data, response, error) in 
     dispatch_async(dispatch_get_main_queue()) {() -> Void in 
      guard let data = data where error == nil else {return} 
      self.img.image = UIImage(data: data) 
     } 
    } 
//setp into the func 
func getDataFromURL(url: NSURL, completion: Handle){ 
    // call async net work by pass url 
    NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in 
     // now data/response/error we have and we invoke the handle 
     completion(data: data, response: response, error: error) 
     } .resume() 

} 
hope it be helpful :D