커링, 상속,

인생노잼시기·2021년 2월 1일
0

🦅 스위프트 문법

목록 보기
1/13

야곰 스위프트 기초 강의

함수형 프로그래밍 패러다임

커링Currying
여러 개의 매개변수를 갖는 함수에서
하나의 매개변수를 갖는 함수로 변환

func sum(first: Int) -> ((Int) -> Int) {
	return { second in first + second}
}

sum(first: 10)(5)	// 15

상속

클래스, 프로토콜 등에서 가능
열거형, 구조체는 불가능
다중상속 불가능

instance, class, static 타입 메서드

final: 상속 불가능
static: 상속 불가능, 메모리에 바로 올라가서 아무데서나 호출 가능

class func: override 가능(상속 가능)
static func = final class: override 불가능(상속 불가능)

타입 메서드나 타입 프로퍼티 사용 이유는? type과 연관될 때 사용

  • static property
    자주 안 변하고 전역 변수 마냥 공통으로 관리하는 공용 자원 느낌일 때 (ex. 색상, 폰트 등)
    자주 재사용되고 생성 비용이 많이드는 object를 미리 만들어 놓고 계속 쓰면 효율 높일 수 있을 때 (ex. dateformatter 등)
  • static method
    간단한 factory 패턴 구현할 때

init, deinit

이니셜라이저 init, 자기 자신의 이니셜라이저를 사용할 때 convenience init
디이니셜라이저 deinit, 인스턴스가 해제되는 시점에 해야할 일
프로퍼티의 초기값이 꼭 필요없을 때! 옵셔널을 사용

class PersonC {
    var name: String
    var age: Int
    var nickName: String?
    convenience init(name: String, age: Int, nickName: String) {
        self.init(name: String, age: Int)
        self.nickName = nickName
    }
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}
let jenny: PersonC = PersonC(name: "jenny", age: 10)
let mike: PersonC = PersonC(name: "mike", age: 15, nickName: "m")

암시적 추출 옵셔널은 인스턴스 사용에 꼭 필요하지만 초기값을 할당하지 않고자 할 때 사용

class Puppy {
    var name: String
    var owner: PersonC!
    init(name: String) {
        self.name = name
    }
    func goOut() {
        print("\(name)가 주인 \(owner.name)와 산책을 합니다")
    }
}
let happy: Puppy = Puppy(name: "happy")
// 강아지는 주인없이 산책하면 안돼요!
//happy.goOut() // 주인이 없는 상태라 오류 발생
happy.owner = jenny
happy.goOut()
// happy가 주인 jenny와 산책을 합니다

실패가능한 이니셜라이저
이니셜라이저 매개변수로 전달되는 초기값이 잘못된 경우 인스턴스 생성에 실패할 수 있습니다. 인스턴스 생성에 실패하면 nil을 반환합니다. 그래서 실패가능한 이니셜라이저의 반환타입은 옵셔널 타입입니다. init?을 사용합니다.

class PersonD {
    var name: String
    var age: Int
    var nickName: String?
    init?(name: String, age: Int) {
        if (0...120).contains(age) == false {
            return nil
        }
        if name.characters.count == 0 {
            return nil
        }
        self.name = name
        self.age = age
    }
}
//let john: PersonD = PersonD(name: "john", age: 23)
let john: PersonD? = PersonD(name: "john", age: 23)
let joker: PersonD? = PersonD(name: "joker", age: 123)
let batman: PersonD? = PersonD(name: "", age: 10)
print(joker) // nil
print(batman) // nil

디이니셜라이저
deinit은 클래스의 인스턴스가 메모리에서 해제되는 시점에 호출됩니다. 인스턴스가 해제되는 시점에 해야할 일을 구현할 수 있습니다. 자동으로 호출되므로 직접 호출할 수 없습니다. 인스턴스가 메모리에서 해제되는 시점은 ARC(Automatic Reference Counting) 의 규칙에 따라 결정됩니다. ARC에 대해 더 자세한 사항은 ARC 문서를 참고하세요.
디이니셜라이저는 클래스 타입에만 구현할 수 있습니다.

class PersonE {
    var name: String
    var pet: Puppy?
    var child: PersonC
    init(name: String, child: PersonC) {
        self.name = name
        self.child = child
    }
    // 인스턴스가 메모리에서 해제되는 시점에 자동 호출
    deinit {
        if let petName = pet?.name {
            print("\(name)\(child.name)에게 \(petName)를 인도합니다")
            self.pet?.owner = child
        }
    }
}
var donald: PersonE? = PersonE(name: "donald", child: jenny)
donald?.pet = happy
donald = nil // donald 인스턴스가 더이상 필요없으므로 메모리에서 해제됩니다
// donald가 jenny에게 happy를 인도합니다

클로저와 completion handler

profile
인생노잼

0개의 댓글