Notice
Recent Posts
Recent Comments
Link
大器晩成
[Extensions] 생성자의 확장 본문
[클래스]
- 편의 생성자만 추가 가능합니다 (즉, 본체의 지정생성자를 호출하는 방법으로만 구현 가능)
- 지정생성자 추가 불가 / 소멸자 추가 불가합니다. (항상 본래의 클래스에서 정의해야 함)
- 클래스의 경우 상우의 지정생성자를 호출하는 델리게이트 어크로스가 발생하기 때문에, 편의생성자만 호출 가능합니다.
*델리게이트 어크로스: 자신의 지정생성자를 호출하는 것
클래스 - 생성자 확장의 예시
// UIColor 기본 생성자
//UIColor(red: <CGFloat>, green: <CGFloat>, blue: <CGFloat>, alpha: <CGFloat>)
var color = UIColor(red: 0.3, green: 0.5, blue: 0.4, alpha: 1)
// 익스텐션 + 편의생성자 조합
extension UIColor {
convenience init(color: CGFloat) { // CGFloat = Core Graphics Float
self.init(red: color/255, green: color/255, blue: color/255, alpha: 1)
} //편의 생성자 구현 후 본체의 지정 생성자 호출
}
//쉽게 객체 생성하는 방법을 제공 가능해집니다
UIColor(color: 1)
- 편의생성자로 생성 후 본체의 지정생성자 호출
[구조체]
- 구조체는 (원래) 편의 생성자가 존재하지 않고, 상속과 관련이 없기 때문에 지정생성자의 형태로도 (자유롭게) 생성자 구현 가능합니다.
- (1) (편의 생성자와 비슷한) 생성자를 추가하여 본체의 지정 생성자를 호출하는 방법으로도 구현 가능합니다.
- (2) 새롭게 지정생성자 형태로 구현하는 것도 가능
[구조체 참고 사항]
- (본체) 직접 생성자 구현하면, 기본 생성자 init() /멤버와이즈 생성자 제공 안 되는 것이 원칙입니다.
- (본체) 모든 저장속성에 기본값제공 + (본체에 직접) 생성자를 구현하지 않았다면, 확정에서 생성자를 정의해도 기본생성자, 멤버와이즈 생성자가 제공됩니다.
- (즉, 확장에서 생성자를 구현해도, 본체에는 여전히 기본 생성자/멤버와이즈 생성자가 자동 제공 되고 본체의 기본 생성자/멤버와이즈 생성자 호출하는 방식으로의 구현도 가능합니다.)
구조체 - 생성자 확장의 예시
구조체는 편의생성자를 제공하지 않는다.
# 구조체는 편의생성자를 제공하지 않는다.
struct Point {
var x = 0.0, y = 0.0
init() {
self.init(x: 0.0, y: 0.0)
}
init(x: Double, y: Double){
self.x = x
self.y = y
}
}
- 편의생성자를 제공하지는 않지만, self.init을 호출함으로 편의생성자처럼 동작할 수 있게 만들 수 있습니다.
생성자를 추가하여 본체의 지정 생성자를 호출하는 방법으로 구현
#1. 생성자를 추가하여 본체의 지정 생성자를 호출하는 방법으로 구현
struct Point {
var x = 0.0, y = 0.0
init(x: Double = 0.0, y: Double = 0.0) {
self.x = x
self.y = y
}
//init(x: Double = 0.0, y: Double = 0.0) // 생성자 미 생성시 기본으로 제공
//init() // 생성자 미 생성시 기본으로 제공
}
extension Point {
init() {
self.init(x: 0.0, y: 0.0)
}
}
#2. 오류 발생 코드
struct Point {
var x = 0.0, y = 0.0
}
extension Point {
init() {
self.init(x: 0.0, y: 0.0)
}
// init(num: Double) {
// self.init(x: num, y: num) //에러 방지
//}
}
- 만약 구조체에 지정생성자가 만들어져 있지 않으면, 확장에서 생성자를 추가할 수 없습니다.
- 구조체는 생성자를 구현하지 않으면 기본적으로 기본생성자와, 멤버와이즈 이니셜라이즈를 제공하기 때문에, 두 번 선언되었다는 오류가 발생합니다.
확장에서 본체의 지정생성자 호출
#1. 확장에서 본체의 지정생성자 호출
struct Point {
var x = 0.0, y = 0.0
init(x: Double, y: Double){
self.x = x
self.y = y
}
}
extension Point {
init() {
self.init(x: 0.0, y: 0.0) // 확장의 생성자에서 본체의 지정생성자 호출
}
}
모든 저장속성에 기본값이 있고, 본체의 생성자를 구현하지 않았을 때,
#1 모든 저장속성에 기본값이 있고, 본체의 생성자를 구현하지 않았을 때,
struct Point {
var x = 0.0, y = 0.0
// 생성자 미 생성시 기본으로 제공
//init(x: Double = 0.0, y: Double = 0.0)
//init()
}
extension Point {
init(num: Double){
self.x = num // 생성자를 직접 구현해도 되고
self.y = num
//self.init(x = num, y = num) // 본체의 지정생성자를 호출해도 된다.
}
}
let a = Point()
let b = Point(num: 10.0)
let c = Point(x: 20.0, y: 30.0)
- 구조체에 확장에서 생성자를 추가할 경우, 기본생성자를 제공하는 구초제의 성격은 남아있어서, 기본생성자, 멤버와이즈 생성자, 확장에서 만든 생성자까지 모두 제공합니다.
애플 공식 예제
// 포인트 구조체
struct Point {
var x = 0.0, y = 0.0
}
// 사이즈 구조체
struct Size {
var width = 0.0, height = 0.0
}
// Rect구조체
struct Rect { // 기본값 제공/생성자 구현안함 ===> 기본 생성자 / 멤버와이즈 생성자가 자동 제공 중
var origin = Point()
var size = Size()
}
let defaultRect = Rect() // 기본생성자
//Rect(origin: Point(x: <Double>, y: <Double>), size: Size(width: <Double>, height: <Double>))
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
size: Size(width: 5.0, height: 5.0)) // 멤버와이즈 생성자
extension Rect {
// 센터값으로 Rect 생성하는 생성자 만들기
// 예외적인 경우 (저장속성에 기본값 + 본체에 생성자 구현 안한 경우, 여전히 기본생성자/멤버와이즈 생성자 제공)
init(center: Point, size: Size) {
let originX = center.x - (size.width / 2)
let originY = center.y - (size.height / 2)
// (1) 본체의 멤버와이즈 생성자 호출 방식으로 구현 가능
self.init(origin: Point(x: originX, y: originY), size: size)
// (2) 직접 값을 설정하는 방식으로도 구현 가능
//self.origin = Point(x: originX, y: originY)
//self.size = size
}
}
// 새로 추가한 생성자로 인스턴스 생성해보기
let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
size: Size(width: 3.0, height: 3.0))
728x90
'iOS > Swift 문법' 카테고리의 다른 글
[Extensions] 멤버의 확장(중첩타입, Nested Types) (0) | 2025.01.07 |
---|---|
[Extensions] 멤버의 확장(서브 스크립트) (0) | 2025.01.05 |
[Extensions] 멤버의 확장(메서드) (0) | 2024.12.23 |
[Extensions] 멤버의 확장 (계산 속성) (0) | 2024.12.23 |
[Extensions] 확장 (0) | 2024.12.23 |