AppDelegate
import UIKit // UIKit 프레임워크를 가져옴. iOS 앱 개발에 필요한 UI 구성 요소와 도구를 제공.
// @main 속성은 이 클래스가 앱의 진입점(entry point)임을 나타냄.
@main
class AppDelegate: UIResponder, UIApplicationDelegate { // AppDelegate 클래스 정의. UIResponder를 상속받아 사용자 입력에 응답하고, UIApplicationDelegate 프로토콜을 준수해 앱 생명주기를 관리.
// 앱이 실행을 완료한 후 호출되는 메서드. 앱 초기화 후 사용자 정의 작업을 추가할 수 있는 지점.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// launchOptions: 앱이 실행된 이유(예: 알림, URL 등)에 대한 정보가 포함될 수 있음.
// 여기서 앱 실행 후 초기 설정(예: 데이터 로드, UI 설정 등)을 커스터마이징 가능.
return true // 초기화가 성공했음을 나타냄.
}
// MARK: UISceneSession Lifecycle - 코드 가독성을 위해 섹션을 구분하는 주석.
// 새로운 장면(scene)이 생성될 때 호출됨. iOS 13 이상에서 멀티 윈도우 지원을 위해 사용.
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// connectingSceneSession: 연결하려는 장면 세션에 대한 정보.
// options: 장면이 생성되는 상황에 대한 추가 정보.
// 이 메서드는 새 장면의 설정을 정의하며, 기본 설정을 반환.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) // "Default Configuration"이라는 이름의 설정을 반환.
}
// 사용자가 장면 세션을 삭제했을 때 호출됨. 더 이상 필요 없는 리소스를 정리하는 데 사용.
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// sceneSessions: 삭제된 장면 세션들의 집합.
// 앱이 실행 중이 아닌 상태에서 세션이 삭제되었다면, 앱 시작 직후 이 메서드가 호출됨.
// 삭제된 장면과 관련된 리소스를 해제하거나 정리하는 코드를 여기에 추가 가능.
}
}
SceneDelegate
import UIKit // UIKit 프레임워크를 가져옴. UI 관련 기능과 장면 관리에 필요.
class SceneDelegate: UIResponder, UIWindowSceneDelegate { // SceneDelegate 클래스 정의. UIResponder를 상속받고, UIWindowSceneDelegate 프로토콜을 준수해 장면 생명주기를 관리.
var window: UIWindow? // 앱의 주요 창(window)을 나타내는 변수. 장면과 연결될 수 있는 UIWindow 객체를 저장.
// 새로운 장면이 세션에 연결될 때 호출됨. 창(window)과 장면(scene)을 설정하거나 초기화하는 데 사용.
func scene(_ scene: UIS siltcene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// scene: 연결하려는 장면 객체.
// session: 장면이 속한 세션 정보.
// connectionOptions: 장면 연결에 대한 추가 정보(예: URL로 열림 등).
// 스토리보드를 사용하면 window 속성이 자동으로 초기화되고 장면에 연결됨.
// 이 메서드는 새 장면/세션이 반드시 새로 생성된 것임을 의미하지 않음(재사용 가능성 있음).
guard let _ = (scene as? UIWindowScene) else { return } // scene이 UIWindowScene 타입인지 확인. 아니면 메서드 종료.
// 여기서 window를 설정하거나 초기 UI를 구성할 수 있음.
}
// 장면이 시스템에 의해 해제될 때 호출됨.
func sceneDidDisconnect(_ scene: UIScene) {
// 장면이 백그라운드로 전환된 직후 또는 세션이 삭제될 때 발생.
// 다음 연결 시 재생성 가능한 리소스를 해제.
// 세션이 삭제되지 않았다면 나중에 다시 연결될 수 있음(참고: `application:didDiscardSceneSessions`).
}
// 장면이 비활성 상태에서 활성 상태로 전환될 때 호출됨.
func sceneDidBecomeActive(_ scene: UIScene) {
// 장면이 사용자와 상호작용할 수 있는 상태가 되었음을 의미.
// 비활성 상태에서 중단되었거나 시작되지 않은 작업(예: 타이머, 애니메이션)을 재개 가능.
}
// 장면이 활성 상태에서 비활성 상태로 전환될 때 호출됨.
func sceneWillResignActive(_ scene: UIScene) {
// 일시적인 중단(예: 전화가 오는 경우)으로 인해 장면이 비활성 상태로 바뀜.
// 현재 진행 중인 작업을 일시 중지하거나 준비할 수 있음.
}
// 장면이 백그라운드에서 포어그라운드로 전환될 때 호출됨.
func sceneWillEnterForeground(_ scene: UIScene) {
// 앱이 다시 사용자에게 보이기 직전 호출.
// 백그라운드 상태에서 변경된 내용을 되돌리거나 UI를 업데이트 가능.
}
// 장면이 포어그라운드에서 백그라운드로 전환될 때 호출됨.
func sceneDidEnterBackground(_ scene: UIScene) {
// 장면이 사용자에게 보이지 않는 상태로 전환됨.
// 데이터를 저장하거나, 공유 리소스를 해제하고, 현재 상태를 복원할 수 있을 만큼의 정보를 저장해야 함.
}
}
ViewController
import UIKit // UIKit 프레임워크를 가져옴. UI 요소와 뷰 컨트롤러 관리에 필요한 도구 제공. class ViewController: UIViewController { // ViewController 클래스 정의. UIViewController를 상속받아 기본적인 뷰 관리 기능 제공. // 뷰가 메모리에 로드된 직후 호출되는 메서드. 뷰의 초기 설정을 수행하는 데 사용. override func viewDidLoad() { super.viewDidLoad() // 부모 클래스(UIViewController)의 viewDidLoad 메서드를 호출하여 기본 설정을 수행. // 뷰가 로드된 후 추가적인 설정 작업(예: UI 구성, 데이터 로드 등)을 이곳에 추가 가능. } }

- 함수 정의부의 값을 매개변수
- 호출시의 값은 아규먼트라고 부름 (함수 내부)



import UIKit
func sayHello() -> Void { // 함수 정의
// 리턴 값이 없는 경우에는 "-> Void " 생략 가능하다
print("Hello")
}
sayHello() // 함수 호출

func add(x:Int, y:Int) -> Int {
return x + y
}
print(add(x: 10, y: 20)) // 30 출력
var x = 10
print(type(of: x)) // Int 출력
print(type(of: add)) // (Int, Int) -> Int
// 함수의 자료형은 (매개변수, 매개변수) -> 리턴형 으로 이루어져 있다.
함수의 자료형은 (매개변수, 매개변수) -> 리턴형 으로 이루어져 있다.

func add(xx x:Int, yy y:Int) -> Int {
// xx: argument label(외부 매개변수) , x: parameter name(내부 매개변수)
return x + y // xx, yy 불가 (Error: Cannot find 'xx' in scope)
}
print(add(xx: 10, yy: 20)) // 30 출력
외부 매개변수명은 생략 가능하다

외부 매개변수명을 생략하는 경우 내부 매개변수명과 같은 이름으로 사용한다

4가지 함수 모두 자료형은 (Int, Int) -> Int 로 모두 같다

func add(first x:Int, second y:Int) -> Int {
// xx: argument label(외부 매개변수) , x: parameter name(내부 매개변수)
print(#function)
return x + y // xx, yy 불가 (Error: Cannot find 'xx' in scope)
}
print(add(first: 5, second: 10))
func add(x:Int, y:Int) -> Int {
// xx: argument label(외부 매개변수) , x: parameter name(내부 매개변수)
print(#function)
return x + y // xx, yy 불가 (Error: Cannot find 'xx' in scope)
}
print(add(x: 10, y: 20)) // 외부 매개변수명을 생략하는 경우 내부 매개변수명과 같은 이름으로 사용한다
func add(_ x: Int, _ y: Int) -> Int {
print(#function)
return x + y
}
print(add(1, 2)) // 매개변수명 생략
func add(_ x: Int, with y: Int) -> Int { // 가장 많이 사용하는 방식
print(#function) // 함수 명을 호출하려면 return 전에 구문을 넣어줘야 됨
return x + y
}
print(add(5, with: 3)) // 출력할 때 첫 번째만 생략함
swift 에서 함수명을 출력할 땐 return 전에 print(#function) 으로 출력한다.
- swift에서 함수명은 콤마 없이 "매개변수명:" (콜론사용) 으로 표기된다.
- 함수명이 같아도 매개변수명이 다르면 모두 사용 가능하다 (함수 중첩)


property(프로퍼티)는 클래스 안에 있는 변수(상수)
1. 초기값이 있거나
2. init을 이용해서 초기화하거나
3. 옵셔널 변수(상수)로 선언(자동으로 nil로 초기화)
- 위 세 가지 중 하나의 조건을 충족해야 한다.




class Man{
var age : Int = 1
var weight : Double = 3.5
// init(){} - 명시하지 않으면 생략되어 있는 코드
func display(){ //인스턴스 메서드
print("나이=\(age), 몸무게=\(weight)")
}
}
var han : Man = Man() // : Man 생략 가능, Man.init() 이 생략되어 있는 코드
han.display() // 나이와 몸무게 출력

class Man{
var age : Int
var weight : Double
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init(age: Int, weight : Double){ // 함수를 출력할 때 init()에 있는 값으로 출력해야 함
self.age = age
self.weight = weight
} //designated initializer
}
var han = Man(age: 20, weight: 35.5)
han.display() // init() 메서드에서 정의된 값이 최종적으로 나옴




class Man{
var age : Int
var weight : Double
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init(age: Int, weight : Double){ // 함수를 출력할 때 init()에 있는 값으로 출력해야 함
self.age = age
self.weight = weight
} //designated initializer
}
class Student : Man {
}
var kim : Student = Student(age: 25, weight: 55.5)
print(kim.age)
kim.display()
var han = Man(age: 20, weight: 35.5)
han.display() // init() 메서드에서 정의된 값이 최종적으로 나옴

self.name = name super.init(age:age, weight:weight) //이 줄을 안쓰면?위 두 줄의 순서를 바꾸면 에러가 발생함

class Man{
var age : Int
var weight : Double
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init(age: Int, weight : Double){
self.age = age
self.weight = weight
}
}
class Student : Man {
var name : String
override func display() {
// 부모 함수와 똑같은 이름의 함수를 만들고 싶다면 함수 선언 앞에 "override" 로 선언해줘야 함
print("이름=\(name), 나이=\(age), 몸무게=\(weight)")
}
init(age: Int, weight : Double, name : String){
self.name = name
super.init(age:age, weight:weight) //이 줄을 안쓰면?
}//error:'super.init' isn't called on all paths before returning from initializer
} //자식 클래스에서 designated initializer를 만들면 부모 init()상속 안됨
var lee : Student = Student(age:20,weight:65.2,name:"홍길동")
lee.display()
부모 함수와 똑같은 이름의 함수를 만들고 싶다면 함수 선언 앞에 "override" 로 선언해줘야 한다
AI 답변: Delegate 패턴은 언어에 관계없이 객체 간의 결합도를 낮추고 역할을 분리하여 유지보수성과 확장성을 높이는 데 사용됩니다. Java에서는 인터페이스를, Swift에서는 프로토콜과 weak 참조를 활용해 구현됩니다.

에러 발생, 아래와 같이 수정해야 함
Fix 후 아래와 같이 변경
아래와 같이 수정 후 실행

// 1. 프로토콜 정의
protocol Speakable {
func speak() -> String
}
// 2. 부모 클래스 정의
class Animal {
var name: String
init(name: String) {
self.name = name
}
}
// 3. 상속과 프로토콜을 함께 사용하는 자식 클래스
class Dog: Animal, Speakable {
func speak() -> String {
return "\(name)이(가) 멍멍 짖습니다!"
}
}
// 4. 사용 예시
let myDog = Dog(name: "바둑이")
print(myDog.speak()) // 출력: "바둑이가 멍멍 짖습니다!"
