콘텐츠로 건너뛰기
Home » Closure

Closure

클로저 내부에서 self를 캡쳐하는 방법 – Swift

항상 [unowned self]를 써야 할까요?

http://stackoverflow.com/questions/24320347/shall-we-always-use-unowned-self-inside-closure-in-swift 의 내용중 일부를 번역하였습니다.

아니오, 분명히 [unowned self]를 쓰지 말아야할 상황이 존재합니다. 특정한 클로져가 호출되었을 때에 그 시점까지 self가 파괴되지 않고 살아있음을 보장할 필요가 있을 때가 있단 말이죠. 예를 한가지 들어봅시다. 비동기 네트워크 요청을 하고, 요청에 대한 응답을 받았을 때 self로부터 어떤 무언가를 호출해야 한다고 가정해봅시다. 비동기 요청이 끝나는 시점 이전에 해당 객체가 해제되어 사라졌다면
프로그램이 뻗고 말겁니다.
그렇다면 언제 unowned selfweak self를 써야하는가? 바로 강한 참조 사이클이 만들어질 때입니다. 이는 두개 이상의 객체가 서로 순환하면서 서로를 순서대로 참조해나갈 때 생길 수 있습니다. 이 경우 사이클 내의 객체들은 어떤 경우에도 항상 참조수 1 이상을 갖기 때문에 파괴되지 않고 리소스를 낭비하게 됩니다.더 보기 »클로저 내부에서 self를 캡쳐하는 방법 – Swift

Swift :: @noescape explained

#@noescape @noescape는 함수 파라미터로 클로져를 선언할 때 해당 클로저내의 모든 정보가 외부로 나갈 수 없음을 명시한다. 표현이 좀 애매한데, @noescape로 선언된 클로져는 다음의 동작만이 가능하다. 클로저가 인자로 전달된 함수 내에서 호출 가능 함수 내에서 다른 함수(이 때 이 다른 함수도 클로져를 @noescape로 선언한 경우에만)로 전달하여 호출할 수 있다. 다른 함수나 클로저에서 역시 @noescape로 선언된 경우에 캡쳐 다음의 경우에는 쓸 수 없게 된다. 다른 지역변수에 대입이 불가하다. 이는 클로져 내의 캡쳐된 모든 변수에 대해서 추가적인 강한 참조를 더할 수 없다는 뜻이다.… 더 보기 »Swift :: @noescape explained

Swift :: @autoclosure explained

#@autoclosure 인자로 클로저를 받는 함수를 하나 생각해보자. func f(pred: () -> Bool) { if pred() { println("It's true") } } 이 함수를 호출할 때에는 클로져 자체를 넘겨주게 된다. f({ 2 > 1}) // 혹은 f{2 > 1} @autoclosure는 함수의 파라미터를 자동으로 클로져로 감싸면서 호출한 시점의 문맥에서 동작하게 한다. 따라서 f(2 > 1) 로 호출할 수 있다. 이 기능의 의미는 인자로 전달되는 표현식의 평가 시점에 있다. 일반적인 함수 호출 흐름에서는 표현식이 함수의 인자로 들어가게 될 때, 함수는 값을 전달받게 되므로 표현식이… 더 보기 »Swift :: @autoclosure explained

클로져 사용방법(Swift)

클로저 사용 시 인자 전달방법

함수의 인자로 클로저를 전달하는 경우를 생각해보자. 배열의 정렬된 사본을 만드는 sorted(_:,_:)의 경우 대략 다음과 같은 시그니처를 가지고 있다.

func sorted<C: SequenceType>(source: C, isOrderedBefore: (C.Geneartor.Element, C.Generator.Element) -> Bool) -> [C.Generator.Element]

만약 정수 배열을 정렬한다고하면 다음과 같이 사용한다.

let arr = [5, 8, 2, 4, 2, 1, 7]
let sortedArr = sorted(arr, { (x:Int, y:Int) -> Bool  in
    return x < y
})

이 때 함수의 마지막 인자는 trailing closure라고 해서 괄호 밖으로 빼낼 수 있다.

let sortedArr = sorted(arr){ (x:Int, y:Int) -> Bool in return x < y }

이때 클로저가 받는 각 인자는 순서대로 $0, $1, … 로 명명하는 것이 가능하다. 이 표현방식도 많이 알려져있는 형태이다. 더 보기 »클로져 사용방법(Swift)

unowned self

Swift의 클래스가 다른 인스턴스를 프로퍼티로 갖게 되는 경우, 만약 두 인스턴스가 서로를 프로퍼티로 참조하게 되면 상호간에 강한 참조 순환1이 발생하게 된다.
이를 해결하기 위해서는 변수 선언시에 weak이나 unowned를 명시하여 약한 참조가 발생하도록 한다. 더 보기 »unowned self

[Swift] 클로저

Closures

Swift에서의 클로저는 코드 블럭과 거의 동일한, 실행 가능한 코드 조각 객체이다. 클로저는 문맥에 따라 주위의 변수들을 캡쳐하여 그 사본을 내부에 저장한다. 함수나 네스팅된 함수는 모두 클로저의 특별한 형태이다.

let myClosure = { (a: Int, b: Int) -> Int in return a + b}

클로저는 그 자체가 문법상 중괄호로 둘러싸져 있으므로 파라미터와 타입시그니처를 그 내부에 작성한다. 여기서 in 문법이 쓰인다. 타입을 추론할 수 있는 경우에는 타입 명시가 필요 없으며, sort 함수의 인자로 쓰이는 등더 보기 »[Swift] 클로저