swift study 12. 메서드 (method)

jess·2022년 7월 14일
0

Swift

목록 보기
12/19
post-thumbnail

🍃 앨런 swift 문법 마스터 스쿨 수업을 듣고 제가 이해한대로 정리해서 올리는 포스팅입니다.

  • 메서드 (method) : 구조체 / 클래스 / (열거형) 의 함수
  • 메서드보다 큰 범주가 함수
class SomeClass {
    func simpleMethod() {
        print("hi")
    }
    func sum(a: Int, b: Int) {
        return a + b
    }
}

📓 메서드 (method)

 1) 인스턴스 메서드 (Insatnace Method)
 2) 타입 메서드 (Type Method)

1) 인스턴스 메서드 (Instance Method)

  • 인스턴스와 연관된 메서드로, "인스턴스를 생성해야만" 호출이 가능하다
class Jess {
    func doSomething() {
        print("열공!")
    }
}

⬆️ 이렇게 아무런 수식 없이 func로 시작하는 메서드는 모두 인스턴스 메서드인 것

class Dog {
    var name: String
    var weight: Double
    ...
    func sit() {
        print("\(name)가 앉았습니다.")
    }
    ...
}
  • 메서드이기 때문에 메모리 공간이 할당되어있지 않다.
  • 접근 시, 인스턴스 이름으로 접근해야 함
    ex) insatnace.method()
  • 값 타입 (구조체/열거형)의 인스턴스 메서드에서 인스턴스 고유의 (저장)속성을 수정할 수 없음
    (수정하려면 mutating 키워드 필요)
  • 오버로딩 지원

✨ 클래스의 인스턴스 메서드

func changeName(name: String) {
    self.name = name
}

✨ 구조체(열거형)의 인스턴스 메서드

mutating func changeName(name: String) {
    self.name = name
}

2) 타입 메서드 (Type Methods)

  • 메서드이지만, 인스턴스의 성격이 아닌 타입 자체의 성격에 가까운 메서드
    (메서드이기에 타입에 메모리 공간이 할당 되어있지 않다.)
  • 인스턴스 생성 없이 형식(type) 이름만 알면 호출이 가능하다
    (인스턴스에 속한 속성이 아니고, 타입 자체에 대한 속성이기에
    내/외부에서 Type.method 이런식으로 접근해야 함)
  • 메서드 선언 시 func 라는 키워드 앞에 static 혹은 class가 붙음
    (static: 재정의 불가, calss: 재정의 가능)
class Jess {
    static func sayHello() {
        print("Hello")
    }
    class func sayBye() {
        print("Bye")
    }
}

⬆️ sayHello, sayBye 메서드는 모두 타입 메서드

3) 서브 스크립트 (Subscripts)

  • 클래스, 구조체, 열거형에서 시퀀스의 멤버 요소에 접근하기 위한 바로가기 첨자
    단일 타입에 여러 서브스크립트를 정의할 수 있다
  • 대괄호를 이용하여 접근 가능하도록 만든 문법
let nums: [Int] = [1,2,3,4]
nums[0] // 1
nums[1] // 2

⬆️ 이렇게 [] 대괄호 안에 index를 넣어줘서 멤버 요소에 접근, 이것이 바로 서브스크립트

3-1) (인스턴스) 서브 스크립트의 직접 구현

 - 클래스, 구조체, 열거형
class SomeData {
    var datas = ["A","B","C","D"]
    subscript(index: Int) -> String {
        get {
            return datas[index]
        }
        set {
            datas[index] = newValue
        }
    }
}
  • 함수의 구현이 특별한 키워드인 subscript로 명명됨
  • 메서드이기 때문에 인스턴스에 메모리 공간이 할당되어 있지 않음
  • 메서드 접근 시, 인스턴스 이름으로 접근 ex)instance[파라미터]
  • 메서드 실행 시, 스택 프레임을 만들고 필요한 데이터를 사용 ➡️ 메서드 종료 시 스택프레임 사라짐

계산속성과 형태는 유사 - getter / setter

  • get 블록만 선언하면 읽기전용 (필수 구현)
  • set 블록은 선택적으로 구현
  • set 블록에서 기본 파라미터 newValue 제공 (직접 파라미터 이름 설정도 가능)

✨ 예시1

class SomeData {
   var datas = ["Apple", "swift", "iOS"]
   subscript(index: Int) -> String {
       get {
           return datas[index]
       }
       set(parameters) {
           datas[index] = parameters     //newValue 가능
       }
   }
}
var data = SomeData()
data[0]            // "Apple" , get
data[0] = "AAA"    // "AAA" , set

✨ 예시2

struct Matrix {
    var data = [["1,2,3"], ["4,5,6"], ["7,8,9"]]
    subscript(row: Int, column: Int) -> String? {
        if row >= 3 || column >= 3 {
            return nil
        }
        return data[row][column]
    }
}
var mat = Matrix()
mat = [0,1]!  // 대괄호 안에 파라미터 2개 필요

3-2) 타입 서브 스크립트

  • 서브스크립터 메서드 앞에 static 또는 class(재정의 가능) 키워드만 붙이면 됨
    ✨ 예시1
    enum Planet: Int {
    case mercury = 1 , venus, earth, mars
       static subscript(n: Int) -> Planet {
           return Planet(rawValue: n)!
       }
    }
    let mars = Planet[4]
    print(mars) // mars

 ** ✨ 예시2**
```swift
class SomeData {
    var datas = ["A", "B", "C", "D"]
    subscript(index: Int) -> String {
        get {
            return datas[index]
        }
        set {
            datas[index] = newValue
        }
    }
}


참고1) 접근제어의 개념

class SomeClass {
    private var name = "이름"
    
    func nameChange(name: String) {
        self.name = name
    }
}
  • 객체의 외부에서 보이지 않도록 코드 내부의 세부 구현을 숨기는 것이 가능 (은닉화)
  • name 속성은 외부에서 볼 수 없음 (접근불가)
    ✨ 접근제어가 필요한 이유
  • 애플이 자신들이 원하는 코드를 감출 수 있음
  • 코드의 영역을 분리시켜 효율적 관리 가능
  • 컴파일 시간 줄어듦 (컴파일러가 해당 변수가 어느 범위에서만 쓰이는지 인지 가능)


참고2) 싱글톤 패턴 (Singleton)

class DataManager {
    static let shared = DataManager()
    // 싱글톤 패턴
    
    var userInfoID = 12345
    
    private init() {}
    
    func dataDownload() {
        // 작업 정의
    }
}
  • static let 이름 = 객체생성()
    : 데이터 영역에 유일한 객체의 주소가 담겨있음
  • 자기 자신을 초기화해서, static let 변수에 할당
  • 앱이 실행하는 동안, 데이터 공유 등 유일하게 1개만 필요로 하는 객체일 때 사용
  • 한 번 생성이 되면, 앱이 종료할 때 까지 1개의 객체로써 메모리에 상주
    (다만, 실제 static 변수로 선언된 것은 접근시에만 지연속성처럼 동작)
    ex) let screen = UIScreen.main

0개의 댓글