컨디션이 난조했지만 늦게라도 마무리한 복습
FAQ를 몇개는 찾아보며 복습했다.
escaping키워드가 생각보다 캡쳐쪽이랑 머릿속에서 겹치면서 헷갈려했던 것 같은데, FAQ를 몇개 보다보니 이해가 되어서(아마도..5점만점에 4점정도 이해했다) 넘어갈 수 있었다. 여러번 보면 더 잘 이해되겠지.
뽀모도로를 다시 도입했다. 어제 공부방법은 유지.
중요한 부분만 정리
클로저의 캡쳐현상과 유사하게 동작하는 @escaping 어트리뷰트 키워드
(아직까지는 이렇게 이해했다)
원함수의 흐름을 벗어나는 상황이 될때(전역변수에 클로저를 저장하면) @escaping 키워드를 사용해서 컴파일러에 정보를 제공해야한다
위의 경우에(@escaping 키워드가 달려있는 경우) 힙영역에 클로저를 저장하여 오래 사용할 수 있도록한다(그래야지 전역변수에서 힙영역의 클로저를 가르켜가며 사용할 수 있기 때문이다. 즉 전역변수에는 클로저가 실행하는 함수코드의 메모리주소 자체가 아닌, 그 함수코드의 메모리주소는 힙영역의 클로저가 가지고 있고, 이 힙영역 클로저의 주소를 전역변수가 할당하게 된다
@autoclosure키워드는 자동으로 클로저를 생성하는 셈 인데, 쉽게 {}중괄호를 제공한다고 생각
단, 오토클로저 키워드는 당연히!파라미터가 없는 클로저에서 작동가능하다
이런 클로저들을 이해하는게 중요한 이유는 실제로 스토리보드가 아닌 하드코딩으로 앱프로젝트 작성시 클로저를 주로 사용하게 되기때문이다. 즉, 어떤 타입으로 선언된 변수에 클로저를 담는다. 클로저내부에는 해당타입을 생성자로 생성해서 변수에 담고, 해당 변수의 속성들을 원하는 것들로 변경한 후에 해당 변수를 리턴하는 구조로 되어있다. 즉 이 내가 원하는 설정들로 변경된 속성을 가지는 인스턴스가 최초에 선언한 변수에 담기게 되는 것이다. 해당 변수+소괄호로 빌드하자마자 해당 인스턴스가 생길 수 있도록하면 빌드하면 내가 제작한 컴포넌트를 확인할 수 있다
함수를 파라미터로, 함수를 리턴하는 함수들을 의미한다 (선언형, 함수형 프로그래밍의 특징이기도하다)
파라미터로 당연히 클로저를 넣어주면 편하게 구현가능하다 (야호)
후행클로저 문법을 주로 사용한다
map{매핑하고 싶은 내용} 이런식
map,filter,reduce, compactMap, flatMap, forEach 등이 있다
고차함수는 sequence, collection 프로토콜을 따르는 컬렉션(배열, 딕셔너리, 세트)에 기본구현되어있다 ( 물론 옵셔널타입 포함)
map: 컬렉션 요소의 아이템을 클로저의 매핑내용으로 매핑해서 새로운 배열을 리턴
filter : 클로저는 참/거짓을 판단하는 내용으로 구성하여 Bool타입을 리턴하고, 참인 아이템들을 모아 새로운 배열을 반환함
reduce : 각 아이템들을 클로저가 제공하는 방식으로 결합해서 마지막 값을 반환함. 초기값, 클로저 모두 필요함 $0은 result(갱신되며), $1은 각 컬렉션의 아이템들이다. 누적값등을 계산할때 유용
map{클로저}.filter{클로저}.reduce(초기값){클로저} 등으로 사용가능
forEach : 각 요소를 빼내서 클로저에 적은 특정한 작업을 한다(Map과 다름)
compactMap : 각요소를 새롭게 매핑하고(map) 옵셔널바인딩을 진행해서, nil인 요소는 제거한 새로운 배열을 반환함
compactMap을 쓰면 [String?]도 [String]으로 자동 unwrapping되는 효과가 있다. 해당 작업들은 filter,map조합으로도 구현은 가능(비추)
flatMap : 중첩배열을 한번(!) 벗겨서 새로운 배열을 반환함. 여러 차수의 중첩배열을 다 벗기고싶으면 반복사용하면 됨.
스위프트 : 객체지향, 프로토콜지향, 함수형
점접근연산자로 인스턴스의 속성을 바로 접근, 재할당하는것은 명령형 문법인셈
옵셔널체이닝 : 점접근자 앞의 타입이 옵셔널이라면(nil일 가능성이 있다면) ?를 점접근자 앞에 붙인다(해당 타입의 뒤에 붙인다)
옵셔널체이닝의 표현식 중 하나라도 옵셔널이면 옵셔널이다
옵셔널체이닝중 하나라도 nil이면 이어지는 표현식을 평가하지 않는다
결국 사용시에는 if let 바인딩, nil 코얼레싱, 강제추출(nil이 확실히 아니라면) 하여 unwrapping시켜야함
헷갈릴수있는 부분을 잘 생각해보면서 복습하자.
함수관련 : honeyBee?.sit?()?.motherBeeName
딕셔너리관련 : honeyBeeHive?["Honey"]?.beeName
옵셔널체이닝에서의 함수실행 : 그냥 하면됨, 하지만 함수가 리턴형이 있을땐 아무리 원 메서드의 리턴타입이 옵셔널이 아니어도 관계없이 표현식 전체가 옵셔널이 되므로(앞에와 비슷하다고 보면됨) 리턴타입이 옵셔널타입이 된다. 옵셔널타입에 값이 없으면 메서드 리턴값도 nil이 된다.