[TIL] 2022-04-18
📌 AlertController
AlertController는 사용자에게 몇몇 선택지를 제공하는데, 각각의 선택지를 AlertAction이라 한다.
AlertAction Style
- default: 기본
- cancel: 선택 취소. AlertController마다 하나씩만 사용할 수 있음.
- destructive: 이 action을 선택하는 데 주의를 요함.
AlertController Style
- alert
cancel 버튼의 위치는 action의 수에 따라 달라진다. action이 2개일 경우 왼쪽에 위치하고, 3개일 경우 최하단에 위치한다.

- actionSheet
action의 수에 상관없이 최하단에 위치한다.

[입력하기] 버튼을 누르면 이메일 혹은 비밀번호 TextField에 커서가 띄워지도록 이렇게 만들어줄 수도 있다. UIAlertAction의 마지막 매개변수인 handler 클로저에는 사용자가 이 action을 선택했을 때 실행할 코드 묶음이 들어간다.
toBeFirstResponder 매개변수로 컨트롤을 받아오므로 이 컨트롤을 FirstResponder로 만들어주는 코드를 클로저에 넣어주면 된다.
✏️ AlertAction handler 클로저 뜯어보기
일단 우리를 괴롭게 하는 [weak toBeFirstResponder]를 빼고 코드를 보자.
let okAction: UIAlertAction
= UIAlertAction(title: "입력하기",
style: UIAlertAction.Style.default) {(action: UIAlertAction) in
toBeFirstResponder?.becomeFirstResponder()}
UIAlertAction의 마지막 매개변수인 handler가
UIAlertAction을 매개변수로 받고 리턴타입이 Void인 클로저인 것이다.
여기서는 리턴타입이 생략된 후행클로저로 구현되어 있다.
UIAlertAction의 정의부로 이동해서 확인해보면 handler의 정의가 우리가 추측한 것이 맞다는 것을 알 수 있다.
입력하기 버튼을 누르면 이 okAction 자기자신이 handler의 action으로 넘어간다. 하지만 우리의 코드는 handler 안에서 이 action을 사용하진 않는다. toBeFirstResponder로 받아온 컨트롤을 FirstResponder로 만들어줄 뿐이다.
그럼 okAction 자기자신이 진짜 action으로 넘어오는 게 맞을까? 확인해보자. handler를 따로 빼서 함수 alertHandler로 만들어주고, 이 함수 안에서 action의 title을 로그로 확인해본다.
okAction과 cancelAction의 handler에 이 함수를 넘겨주어서 코드를 재사용했고, 호출은 self.alertHandler(_:)로 해주든 alertHandler로 해주든 상관 없이 정상동작한다. << 왜 ????
func alertHandler(_ alertAction: UIAlertAction) {
guard let actionTitle = alertAction.title else {
return
}
print("alertHandler >> \(actionTitle)")
}
private func showAlert(message: String, control toBeFirstResponder: UIControl?) {
let alert: UIAlertController = UIAlertController(title: "알림",
message: message,
preferredStyle: UIAlertController.Style.alert)
let okAction: UIAlertAction = UIAlertAction(title: "입력하기",
style: UIAlertAction.Style.default,
handler: self.alertHandler(_:))
let cancelAction: UIAlertAction = UIAlertAction(title: "취소",
style: UIAlertAction.Style.cancel,
handler: alertHandler)
alert.addAction(okAction)
alert.addAction(cancelAction)
self.present(alert, animated: true) {
print("얼럿 화면에 보여짐")
}
}
입력하기 버튼과 취소 버튼을 차례로 눌러주었고, 로그가 제대로 찍히는 모습이다.
✏️ 순환참조
이제 그럼 [weak toBeFirstResponder]를 추가한 원래 코드로 돌아와보자.
let okAction: UIAlertAction
= UIAlertAction(title: "입력하기",
style: UIAlertAction.Style.default) { [weak toBeFirstResponder] (action: UIAlertAction) in
toBeFirstResponder?.becomeFirstResponder() }
weak은 왜 쓰는 걸까? 순환참조에 대해 미리 알 필요가 있다.
ARC(Automatic Reference Counting)
- 참조된 횟수(reference count)를 추적해 더 이상 참조되지 않는 인스턴스를 메모리에서 해제해 주는 것
순환참조
- 서로가 서로를 참조하고 있어서 메모리 해제가 절대 되지 않는 상황
- ARC가 메모리 해제에 대한 개발자의 부담을 덜어주기는 하지만 자칫 잘못하면 순환참조가 발생할 수도 있음
weak
- 해당 인스턴스의 소유권을 가지지 않고, 주소값만 가지고 있는 포인터 개념
- 자신이 참조하는 인스턴스의 참조 횟수(reference count)를 증가시키지 않음
>> https://babbab2.tistory.com/83 요기 글 정독해보기 !! <<
결국 [weak toBeFirstResponder]는, 강한 참조 순환을 방지하기 위한 클로저의 캡쳐 리스트이다.
얘기가 많이 샜다. 다시 첫 코드캡쳐로 돌아가자. 마지막 줄에 present 메소드도 후행 클로저를 사용하는데, completion이라는 이름을 갖는 매개변수에 클로저를 넣어준 것이다. 마찬가지로 이 모달 애니메이션을 띄운 후에 실행할 코드 묶음이 들어간다.
매개변수 이름이 handler, completion인 것들은 대부분 클로저를 전달받는다.
📌 JSONDecoder
JSON 파일을 Asset에 등록하여 사용할 때 필요한 클래스이다.
이렇게 생긴 Questions.json 파일을 가져와보자.
프로젝트에 JSON 파일을 Asset에 등록할 때, dataset 확장자로 삽입해야 한다. 우리의 Questions.dataset 에는 Contents.json과 Questions.json이 들어있다. NSDataAsset 클래스를 이용하면 이 dataset을 코드에서 가져와 사용할 수 있다.
Question.swift
import Foundation
import UIKit
struct Question: Codable {
let d: String
let i: String
let s: String
let c: String
}
extension Question {
static var all: [Question] = {
guard let dataAsset: NSDataAsset = NSDataAsset(name: "Questions") else {
return []
}
let jsonDecoder: JSONDecoder = JSONDecoder()
do {
return try jsonDecoder.decode([Question].self, from: dataAsset.data)
} catch {
return []
}
}()
}
all 변수에는 [Question] 배열을 리턴하는 함수를 저장한다. 이 함수를 들여다보자.
Asset을 가져올 때는 파일이 없을 수도 있기 때문에 옵셔널 바인딩을 해 주는 것이 안전하다. guard let 구문으로 이를 수행했다. Asset을 무사히 가져왔다면 JSONDecoder 인스턴스를 만들어서 decode의 from 인자에 넣어준다.
decode 정의부를 보면 throws로 구현되어 있다. 디코딩 도중에 에러가 발생할 가능성을 내포한 메소드이므로 decode를 사용할 때 try를 반드시 같이 써주어야 한다. // https://babbab2.tistory.com/61
Author And Source
이 문제에 관하여([TIL] 2022-04-18), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@hygge/TIL-2022-04-18저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)