[Swift] 기본 문법 (4)

니나노개발생활·2022년 2월 24일
0

💡ah-ha

목록 보기
49/51
post-thumbnail
  • 프로그래머가 데이터를 용도에 맞게 표현하고자 할 때 용이
  • 프로퍼티와 메소드를 사용해 구조화된 데이터와 기능을 가질 수 있어 하나의 새로운 사용자 정의 데이터 타입을 생성

구조체

struct 구조체 이름 {
 	프로퍼티와 메소드 = 멤버
}

// 구조체: 파스칼로 정의
struct User {
    var nickname: String
    var age: Int
    
    
    // 메소드 정의
    func information() {
        print("\(nickname) \(age)")
    }
}

var user = User(nickname:"fall", age:23)

user.nickname.
// 메소드 호출
user.information()

클래스

class 클래스 이름 {
    프로퍼티와 메소드
}

class Dog {
    var name: String = ""
    var age: Int = 0
    
    // 생성자 초기화(뒤에 정리)
    init() {
    }
    
    // 메소드 정의
    func information() {
        print("\(name) \(age)")
    }
}

var dog = Dog()
dog.name = "fall"
// 메소드 호출
dog.information()

Init

  • 초기화 구문
  • 클래스 구조체 또는 열거형의 인스턴스를 사용하기 위한 준비 과정
  • 인스턴스의 프로퍼티마다 초기값을 설정해주고 새 인스턴스를 사용하기 전 필요한 설정을 해주기 위해 사용
init(매개변수: 타입, ...) {
	// 프로퍼티 초기화
    // 인스턴스 생성시 필요한 설정을 해주는 코드 작성
}

class Dog {
    var name: String = ""
    var age: Int = 0
    
    // 생성자 초기화 ex) dog
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    // ex) dog2
    // 매개변수로 전달받지 않고 생성자 안에서 프로퍼티를 전달하여 초기화
	//기본 제공되는 생성자 외에 사용자 정의 생성자를 이용해 생성자 정의
    init(age: Int) {
        self.name = "fall"
        self.age = age
    }
    
    // ex3) dog3
	//이니셜라이저와 반대 디이니셜라이저(deinit - class에서만) > 인스턴스가 메모리에 해제되기 직전에 호출
	// 인스턴스가 필요하지 않으면 자동으로 메모리에서 소멸을 시키기 때문에 deinit이 호출
    deinit {
        print("deinit user")
    }
}

var dog = Dog(name: "fall", age: 23)
dog.name
dog.age

var dog2 = Dog(age: 27)
dog2.name
dog2.age

var dog3: Dog? = Dog(age:23)
dog3 = nil

프로퍼티

  • 클래스, 구조체 또는 열거형 등에 관련된 값
  • 소속된 변수 및 속성

저장 프로퍼티

  • 인스턴스의 변수 또는 상수
  • 가장 간단한 방법
  • 변수나 상수로 선언된 클래스나 구조체 인스턴스의 일부분으로 저장
struct Dog {
    // 저장 프로퍼티
    var name: String
    let gender: String
}
var dog = Dog(name: "fall", gender: "female")
print(dog) //Dog(name: "fall", gender: "female") 프로퍼티에 값이 저장되는 것 = 저장 프로퍼티

dog.name = "mayo"
//dog.gender = "male" // 상수로 선언된 프로퍼티는 값을 변경할 수 없다.

let dog2 = Dog(name: "mayo", gender: "male")
//dog2.name="nez"
// 구조체 인스턴스가 상수로 선언되었기 때문에 값을 변경할 수 없다.
// 구조체는 {value, 값} 타입 > 상수가 되면 내부 프로퍼티도 다 상수가 된다.
class Cat {
    var name: String
    let gender: String
    
    init(name: String, gender: String) {
        self.name = name
        self.gender = gender
    }
}
let cat = Cat(name: "mayo", gender: "male")
cat.name = "nez"
print(cat.name) //nez
// 상수로 선언해도 프로퍼티의 값이 변경된다.
// 프로퍼티 옵저버
class Account {
    var credit: Int = 0 {
        // 값이 저장되기 직전에 호출
        // 새로 저장될 프로퍼티의 값을 상수 매개변수(지정하지 않으면 newValue)로 전달
        willSet {
            print("잔액이 \(credit)원에서 \(newValue)원으로 변경될 예정입니다.")
        }
        // 값이 저장된 직후에 호출
        // 프로퍼티의 기존값이 상수 매개변수(지정하지 않으면 oldValue)로 전달
        didSet {
            print("잔액이 \(oldValue)원에서 \(credit)원으로 변경되었습니다.")
        }
    }
}

var account = Account()
account.credit=1000

연산 프로퍼티

  • 특정 연산을 실행하는 결과값
  • 클래스, 구조체, 열거형에서 사용 가능
  • 값을 직접 저장하진 않지만 getter, setter를 사용해 다른 프로퍼티와 값에 접근할 수 있다.
struct Stock {
    var price: Int
    var amount: Int
    // 연산형 프로퍼티
    var purchasePrice: Int {
        // 값을 연산
        get {
            return price * amount
        }
        // 프로퍼티에 전달
        set(newPrice) {
            price = newPrice / amount
        }
    }
}

var stock = Stock(price: 2300, amount: 3)
print(stock) //Stock(price: 2300, amount: 3)
stock.purchasePrice //6900
stock.purchasePrice = 3000
stock.price //1000
  • 인스턴스 내외부의 값을 계산해서 적절한 값을 돌려주는 접근자 역할이나 내부 프로퍼티의 값을 간접적으로 설정하는 설정자 역할
  • set()이 없으면 읽기 전용 프로퍼티가 되어 값은 변경할 수 없음
  • set에 매개변수를 지정하지 않으면 newValue로 적용됨.

타입 프로퍼티

  • 특정 타입에서 사용되는 프로퍼티
  • 인스턴스 생성없이 객체 내의 프로퍼티에 접근
  • 프로퍼티 타입 자체와 연결
struct SomeStructure {
    // 타입 프로퍼티
    static var storedTypeProperty = "some value"
    static var computedTypeProperty: Int {
        return 1
    }
}
SomeStructure.computedTypeProperty
SomeStructure.storedTypeProperty
  • 변수에 클래스를 할당해 인스턴스를 생성하지 않고도 프로퍼티를 사용할 수 있다.

클래스와 구조체의 차이

공통점

  • 값을 저장할 프로퍼티를 선언할 수 있다.
  • 함수적 기능을 하는 메서드를 선언할 수 있다.
  • 내부 값에 .을 사용하여 접근할 수 있다.
  • 생성자를 사용해 초기 상태를 설정할 수 있다.
  • extension을 사용해 기능을 확장할 수 있다.
  • protocol을 채택하여 기능을 설정할 수 있다.

차이점

클래스

  • 참조 타입
  • ARC로 메모리를 관리
  • 상속이 가능
  • 타입 캐스팅을 통해 런타임에서 클래스 인스턴스의 타입을 확인할 수 있다.
  • deinit을 사용해 클래스 인스턴스의 메모리 할당을 해제할 수 있다.
  • 같은 클래스 인스턴스를 여러 개의 변수에 할당한 뒤 값을 변경 시키면 모든 변수에 영향을 준다.(메모리가 복사)
class SomeClass {
    var count: Int = 0
    
}
var class1 = SomeClass()
var class2 = class1
var class3 = class1
class3.count = 2
class1.count // 2
  • 참조 타입이기 때문에 같은 클래스 인스턴스를 할당한 변수의 값을 변경시키면 참조된 인스턴스의 값이 변경 = 변수를 복사하더라도 원본과 복사본이 같은 값을 가짐

구조체

  • 값 타입
  • 구조체 변수를 새로운 변수에 할당할 대마다 새로운 구조체가 할당된다.
  • 같은 구조체를 여러 개의 변수에 할당한 뒤 값을 변경시키더라도 다른 변수에 영향을 주지 않는다.(값 자체를 복사)
struct SomeStruct {
    var count: Int = 0
}
var struct1 = SomeStruct()
var struct2 = struct1
var struct3 = struct1
struct2.count = 3
struct3.count = 4
struct1.count // 0
struct2.count // 3
struct3.count // 4
  • 값 타입이기 때문에 같은 구조체 인스턴스를 할당하더라도 매번 새로운 메모리가 할당된다.

패스트캠퍼스 ios 앱개발 swift 강의를 듣고 작성된 글입니다.

profile
깃헙으로 이사중..

0개의 댓글