swift 기초 - assert , guard , protocol
[1] assert 와 guard
애플리케이션 동작 도중에 생성하는 다양한 결과값을 동적으로 확인하고
안전하게 처리할 수 있도록 확인하고 빠르게 처리할 수 있다.
assert(condition:Bool, message:String)
assert 함수는 디버깅 모드에서만 동작한다.
배포하는 애플리케이션에서는 제외 된다.
주로 디버깅 중 조건의 검정을 위하여 사용한다.
[1-1] 기본 예제
var someInt : Int = 0
//조건에 부합하므로 지나간다.
assert(someInt == 0, "someInt != 0")
someInt = 1
//조건에 부합하지 않으므로 지나가지 않는다.
//assert(someInt == 0, "someInt != 0")
//Assertion failed: someInt != 0: file test2/main.swift, line 28
[1-2] 예제 2
//옵셔널 파라미터를 매개변수로 받는다.
func functionWithAssert(age:Int?) {
print(age) //Optional(50)
//age 가 nil이면 여기서 걸린다.
assert(age != nil, "age == nil")
assert((age! >= 0) && (age! <= 130), "나이값 입력이 잘못되었습니다.")
print("당신의 나이는 \(age!)세 입니다.")
}
functionWithAssert(age: 50) //당신의 나이는 50세 입니다.
//functionWithAssert(age: nil) //Assertion failed: age == nil: file test2/main.swift, line 43
//functionWithAssert(age: -1) //Assertion failed: 나이값 입력이 잘못되었습니다.: file test2/main.swift, line 45
[2] Early Exit (guard let)
guard를 사용하여 잘못된 값의 전달 시
특정 실행구문을 빠르게 종료한다.
디버깅 모드 뿐만 아니라 어떤 조건에서도 동작한다.
guard의 else 블럭 내부에는 특정 코드블럭을 종료하는 지시어 (return, break 등)가 필수
타입 캐스팅, 옵셔널과도 자주 사용된다.
그 외 단순 조건 판단 후, 빠르게 종료할 때도 용이하다.
[2-1] guard 예제
func funcWithGuard(age:Int?){
//옵셔널 age 값이 nil 이 아니면 unwrappedAge 변수에 할당한다.
//옵셔널 age 값이 130 보다 작고, 0보다 크면 unwrappedAge 변수에 할당한다.
guard let unwrappedAge = age,
unwrappedAge < 130,
unwrappedAge >= 0 else {
print("나이값 입력이 잘못되었습니다.")
return
}
print("당신의 나이는 \(unwrappedAge) 입니다.")
}
var count = 1
while true {
guard count < 3
else {
break
}
print(count)
count += 1
//1
//2
}
[2-2] guard 예제
//매개 변수는 딕셔너리 타입이다
func someFunction(info : [String:Any]) {
//딕셔너리의 key의 name 타입이 String 일때, 옵셔널값을 name에 할당
guard let name = info["name"] as? String else {
return
}
//딕셔너리 key age 타입이 Int 일때, 또 age 가 0 보다 클때만 옵셔널값을 age에 할당
guard let age = info["age"] as? Int , age >= 0 else {
return
}
print("\(name) : \(age)")
}
someFunction(info: ["name" : "jenny" , "age" : "10"]) //guard 를 통과 못한다. - 타입이 안맞음
someFunction(info: ["name" : "kyo"]) //guard 를 통과 못한다. - 타입 안맞음
someFunction(info: ["name" : "hong" , "age" : 10]) //hong : 10
[3] 프로토콜
구조체, 클래스, 열거형은 프로토콜을 채택해서
프로토콜의 요구사항을 실제로 구현할 수 있다.
어떤 프로토콜의 요구사항을 모두 따르는 타입은 그 프로토콜을 준수한다라고 표현한다.
프로토콜의 요구사항을 충족시키려면 프로토콜이 제시하는 기능을 모두 구현해야 한다.
정의
protocol <프로토콜이름>
{
//정의부
}
[3-1] 프로토콜 정의
protocol Talkable {
/*
<프로퍼티 요구>
프로퍼티 요구는 항상 var 키워드를 사용한다.
get은 읽기만 가능해도 상관없다는 뜻이며
get과 set을 모두 명시하면 읽기 쓰기 모두 가능한 프로퍼티여야 한다.
*/
var topic : String {get set}
var language : String {get}
//<메서드 요구>
func talk()
//초기화 메소드 요구
init(topic:String , language: String)
}
[3-2] 프로토콜 채택 및 준수
//Person 구조체는 Talkable 프로토콜을 채택했습니다.
struct Person:Talkable {
//[1] 프로퍼티 요구 수준
var topic: String
let language: String
//[2] 메서드 요구 준수
func talk() {
print("\(topic)에 대해 \(language)로 말합니다.")
}
//[3] 초기화 요구 준수
init(topic:String , language: String){
self.topic = topic
self.language = language
}
}
[3-3] 프로토콜 상속
프로토콜은 클래스와 다르게 다중상속이 가능하다.
protocol 프로토콜이름 : 부모 프로토콜 목록{
}
//부모 프로토콜
protocol Readable {
func read()
}
//부모 프로토콜
protocol Writeable {
func write()
}
//자식 프로토콜
protocol ReadSpeakable : Readable {
//func read()
func speak()
}
//자식 프로토콜
protocol ReadWriteSpeakable : Readable, Writeable {
//func read()
//func write()
func speak()
}
//자식 프로토콜 준수
struct SomeType: ReadWriteSpeakable {
//프로토콜 메소드 구현
func speak() {}
func read() {}
func write() {}
}
[3-4] 클래스 상속과 프로토콜
클래스에서 상속과 프로토콜 채택을 동시에 하려면
상속받으려는 클래스를 먼저 명시하고
그 뒤에 채택할 프로토콜 목록을 작성한다.
//부모 클래스 : 프로토콜
class SuperClass : Readable{
func read(){}
}
//자식 클래스 : 부모클래스, 프로토콜s...
class SubClass: SuperClass , Writeable, ReadSpeakable {
func write() {}
func speak() {}
}
[3-5] 프로토콜 준수 확인
인스턴스가 특정 프로토콜을 준수하는지 확인할 수 있다.
is as 연산자 사용
let sup: SuperClass = SuperClass()
let sub: SubClass = SubClass()
var someAny: Any = sup
someAny is Readable // true
someAny is ReadSpeakable // false
someAny = sub
someAny is Readable // true
someAny is ReadSpeakable // true
someAny = sup
if let someReadable: Readable = someAny as? Readable {
someReadable.read()
} // read
if let someReadSpeakable: ReadSpeakable = someAny as? ReadSpeakable {
someReadSpeakable.speak()
} // 동작하지 않음
someAny = sub
if let someReadable: Readable = someAny as? Readable {
someReadable.read()
} // read
참고
'아이폰 개발 > Swift' 카테고리의 다른 글
[스탠포드]Swift 강좌 - MVC 패턴 (0) | 2021.03.09 |
---|---|
[스탠포드]Swift 강좌 - ios 구조 (0) | 2021.03.09 |
swift 기초 - 옵셔널 체이닝, 타입캐스팅 (0) | 2021.03.05 |
swift 기초 - 상속, 인스턴스의 생성과 소멸 (0) | 2021.03.04 |
swift 기초 - 클로저 , 프로퍼티, 프로퍼티 감시자 (0) | 2021.03.04 |