ViewController.swift

//
//  ViewController.swift
//  aa
//
//  Created by 소프트웨어컴퓨터 on 2025/03/26.
//

import UIKit // UIKit 프레임워크를 임포트하여 UI 요소를 사용할 수 있도록 함

// ViewController 클래스를 정의, UIViewController를 상속받음
class ViewController: UIViewController {

    // 뷰가 메모리에 로드될 때 호출되는 메서드
    override func viewDidLoad() {
        super.viewDidLoad() // 부모 클래스의 viewDidLoad() 메서드를 호출하여 기본 초기화 수행
        
        // 뷰가 로드된 후 추가적인 설정을 할 수 있는 곳
        // 여기에서 UI 요소를 초기화하거나 데이터를 설정할 수 있음
    }
}

 

 

AppDelegate.swift

//
//  AppDelegate.swift
//  aa
//
//  Created by 소프트웨어컴퓨터 on 2025/03/26.
//

import UIKit // UIKit 프레임워크를 임포트하여 UI 관련 기능을 사용 가능하게 함

@main // 이 클래스가 프로그램의 진입점임을 나타냄
class AppDelegate: UIResponder, UIApplicationDelegate { // AppDelegate 클래스 정의, UIResponder 및 UIApplicationDelegate 프로토콜을 준수

    // 애플리케이션이 시작될 때 호출되는 메서드
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 애플리케이션이 실행된 후 사용자 정의를 위한 오버라이드 포인트
        return true // 애플리케이션이 성공적으로 시작되었음을 나타냄
    }

    // MARK: UISceneSession Lifecycle // UISceneSession 생명주기 관련 메서드 구분을 위한 주석

    // 새로운 장면 세션이 생성될 때 호출되는 메서드
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // 새로운 장면을 생성하기 위한 설정을 선택하는 메서드
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) // 기본 설정을 사용하여 새로운 장면 구성 반환
    }

    // 사용자가 장면 세션을 폐기할 때 호출되는 메서드
    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // 애플리케이션이 실행 중이지 않을 때 세션이 폐기되면, 이 메서드가 호출됨
        // 폐기된 장면에 특정한 자원을 해제하는 데 사용
    }
}
 func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
  • _의 사용: _를 사용하면 외부 이름 생략 가능

 

  • configurationForConnecting connectingSceneSession: 

      -configurationForConnecting은 메서드를 호출할 때 사용되는 argument로, 메서드의 목적을 명확히 설명

      -connectingSceneSession은 메서드 정의에서 사용되는 parameter로, 메서드 내부에서 해당 값을 참조하는 데 사용

 

  • options는 application(_:configurationForConnecting:options:) 메서드의 매개변수 중 하나로, 새로운 장면 세션을 연결할 때 사용할 수 있는 추가적인 설정이나 정보를 포함하는 객체

 

  •  Set<UISceneSession>: 제네릭 (집합)

 

 

 

  • 함수에서 정의부의 값을 매개변수, 호출시 값을 아규먼트라고 부름

        함수 내부에서 사용: parameter

        argument함수 에서 호출할때

 

  • 함수 명: application(_:configurationForConnecting:options:)

1. 아규먼트 레이블 (Argument Label)

 

  • _ application:
    외부에서 이 매개변수를 호출할 때 사용할 아규먼트 레이블입니다. _가 붙어있어 이 레이블이 생략된다는 것을 의미합니다. 즉, 호출 시에는 application이라는 이름을 사용하지 않고, 단순히 매개변수의 타입만 사용합니다.
  • configurationForConnecting:
    이 매개변수의 외부 이름으로, 메서드를 호출할 때 사용됩니다. 이 이름은 메서드의 목적을 설명합니다.
  • options:
    이 매개변수의 외부 이름으로, 메서드 호출 시 사용됩니다. 여기서도 호출 시 options라는 이름이 사용됩니다.

 

2. 아규먼트 네임 (Argument Name)

 

  • application:
    메서드 본문에서 사용할 내부 이름입니다. UIApplication 타입의 객체를 참조하기 위해 사용됩니다.

 

  • connectingSceneSession:
    메서드 본문 내에서 사용할 내부 이름입니다. UISceneSession 타입의 객체를 참조합니다.

 

  • options:
    메서드 본문 내에서 사용할 내부 이름입니다. UIScene.ConnectionOptions 타입의 객체를 참조합니다.

 

3. 자료형 (Type)

 

  • UIApplication:
    application 매개변수의 타입입니다. 현재 실행 중인 애플리케이션의 인스턴스를 나타냅니다.

 

  • UISceneSession:
    connectingSceneSession 매개변수의 타입입니다. 새로운 장면 세션을 나타내며, 사용자가 새 장면을 여는 과정에서 생성되는 객체입니다.

 

  • UIScene.ConnectionOptions:
    options 매개변수의 타입입니다. 장면 세션을 연결할 때 사용할 수 있는 추가적인 설정이나 정보를 포함하는 객체입니다.

 

4. 반환 타입 (Return Type)

 

  • -> UISceneConfiguration:
    이 메서드가 반환하는 타입입니다. UISceneConfiguration 객체를 반환하여 새로운 장면의 설정을 정의합니다.

import UIKit

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

 

 

 

import UIKit

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

//int add(int x, int y) { //C, C++
//    return(x+y);
//}
//add(10,20);

// commend+/주석처리

func add(x:Int, y:Int) -> Int {
    return x+y
}
add(x: 10,y: 20)

 

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

함수의 타입 (자료형,자료형,…) -> 리턴형 (Int, Int) -> Int 리턴형이 Void형이면 ()

 

 

func add(xx x:Int, yy y:Int) -> Int {//첫번째는 호출(argument label), 두번째는 함수 정의 (parameter name)
    return x+y
}
print(add(xx: 10,yy: 20))//30


func add(x:Int, y:Int) -> Int {//하나만 있을땐, 내부 외부 전부 같은거
    return x+y
}
print(add(x: 10,y: 20))//30

//#1
func add(xx x:Int, yy y:Int) -> Int {//첫번째는 호출(argument label), 두번째는 함수 정의 (parameter name)
    print(#function)//add(xx:yy:)
    return x+y
}
print(add(xx: 10,yy: 20))//30

//#2
func add(x:Int, y:Int) -> Int {//하나만 있을땐, 내부 외부 전부 같은거
    print(#function)//add(x:y:)
    return x+y
}
print(add(x: 10,y: 20))//30

//#3
func add(_ x:Int, _ y:Int) -> Int {//
    print(#function)//add(_:_:)
    return x+y
}
print(add(1,2))//3

//#4
func add(_ x:Int, with y:Int) -> Int {//
    return x+y
}
print(add(5,with:3))//8

함수의 이름은 다 다름

:의 개수가 매개변수의 개수다, 콤마 없음

 

class Man {
    var age : Int = 0
    //클래스 안에 있는 변수를 프로퍼티라고 하는데 값이 있어야됨, =0 이런식으로 (값이 없으면 에러남)
    //옵셔널 방법도 있음 var age : Int?
}
var x : Int
var han : Man = Man()
han.age = 10
print(han.age)//10

 

메서드 정의

class Man{
    var age : Int = 1
    var weight : Double = 3.5
    //init(){}
    func display(){ //인스턴스 메서드
        print("나이=\(age), 몸무게=\(weight)")
    }
}

var han : Man = Man()
han.display()

 

class Man { // 'Man'이라는 클래스 정의
    var age: Int // 'age'라는 저장 속성 정의 (정수형)
    var weight: Double // 'weight'라는 저장 속성 정의 (실수형)
    
    // 'display' 메서드 정의 - Man 객체의 나이와 몸무게를 출력
    func display() {
        print("나이=\(age), 몸무게=\(weight)") // 나이와 몸무게를 출력
    }
    
    // Designated initializer - Man 객체를 초기화하는 메서드
    init(age: Int, weight: Double) {
        self.age = age // 매개변수 'age'를 저장 속성 'age'에 할당
        self.weight = weight // 매개변수 'weight'를 저장 속성 'weight'에 할당
    } // 초기화 메서드는 객체 생성 시 자동으로 호출됨
}

// 'Man' 클래스의 인스턴스를 생성하고 'han'이라는 변수에 할당
var han: Man = Man(age: 20, weight: 35.5)

// 'han' 인스턴스의 'display' 메서드를 호출하여 나이와 몸무게를 출력
han.display()

designated initializer는 클래스의 주요 초기화 메서드로, 클래스의 모든 속성을 초기화하는 책임을 가진 초기화자

 

class Man{
    var age : Int
    var weight : Double
    func display(){
        print("나이=\(age), 몸무게=\(weight)")
    }
    init(age: Int, weight : Double){
        self.age = age
        self.weight = weight
    } //designated initializer//init메소드는 자동 호출
}
class Student : Man{
    
}
var kim : Student = Student(age: 25, weight: 55.5)
//print(kim.age)//25
kim.display()//나이=25, 몸무게=55.5
var han : Man = Man(age: 20, weight: 35.5)
han.display()//나이=20, 몸무게=35.5

 

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
    func displayS() {
        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.displayS()
lee.display()

 

 self.name = name
        super.init(age:age, weight:weight) //이 줄을 안쓰면?

위 두줄의 순서를 바꾸면 안되는 이유: self.name = name을 super.init(...) 호출 이전에 수행하면, 초기화되지 않은 self를 사용하는 것이 되어 에러가 발생합니다. 따라서 반드시 부모 클래스의 초기화를 먼저 수행한 후, 자식 클래스의 속성을 초기화해야 함

 

class Man { // 'Man'이라는 클래스 정의
    var age: Int // 'age'라는 저장 속성 정의 (정수형)
    var weight: Double // 'weight'라는 저장 속성 정의 (실수형)
    
    // 'display' 메서드 정의 - Man 객체의 나이와 몸무게를 출력
    func display() {
        print("나이=\(age), 몸무게=\(weight)") // 나이와 몸무게를 출력
    }
    
    // Designated initializer - Man 객체를 초기화하는 메서드
    init(age: Int, weight: Double) {
        self.age = age // 매개변수 'age'를 저장 속성 'age'에 할당
        self.weight = weight // 매개변수 'weight'를 저장 속성 'weight'에 할당
    }
}

class Student: Man { // 'Student'라는 클래스 정의, 'Man' 클래스를 상속받음
    var name: String // 'name'이라는 저장 속성 정의 (문자열형)
    
    // display 메서드를 오버라이드 - Student 객체의 이름, 나이, 몸무게를 출력
    override func display() {
        // 오버라이드의 목적: 부모 클래스의 'display' 메서드를 재정의하여
        // Student 클래스에 맞는 출력 형식으로 변경
        print("이름=\(name), 나이=\(age), 몸무게=\(weight)") // 이름, 나이, 몸무게를 출력
    }
    
    // Designated initializer - Student 객체를 초기화하는 메서드
    init(age: Int, weight: Double, name: String) {
        self.name = name // 매개변수 'name'을 저장 속성 'name'에 할당
        super.init(age: age, weight: weight) // 부모 클래스의 designated initializer 호출
        // 위 줄이 없으면 에러 발생: 'super.init'이 모든 경로에서 호출되지 않음
    }
}

// 'Student' 클래스의 인스턴스를 생성하고 'lee'라는 변수에 할당
var lee: Student = Student(age: 20, weight: 65.2, name: "홍길동")

// 'lee' 인스턴스의 'display' 메서드를 호출하여 이름, 나이, 몸무게를 출력
lee.display()

override func display() { ... } 
// 오버라이드의 목적: 부모 클래스의 'display' 메서드를 재정의하여
// Student 클래스에 맞는 출력 형식으로 변경

 


델리게이트(Delegate) 디자인 패턴은 한 객체가 다른 객체에게 특정 작업을 맡기는 방법

 

프로토콜(protocol) :특정 클래스와 관련없는 함수(메서드)들의 선언 집합

 

Swift에서 프로토콜의 속성(property)은 접근 제어를 명시해야됨

즉, 속성이 읽기 전용인지(get), 쓰기 가능인지(get set) 명시해야됨
따라서, Runnable 프로토콜의 x 속성에 대해 { get } 또는 { get set }을 추가해야 함

 

메시지 "Type 'Man' does not conform to protocol 'Runnable'"는 Man 클래스가 Runnable 프로토콜의 요구사항을 충족하지 않음을 나타냄

Runnable 프로토콜은 x라는 읽기/쓰기 속성과 run()이라는 메서드를 요구하고 있음

 

protocol Runnable { // 'Runnable'이라는 프로토콜 정의
    var x: Int { get set } // 'x'라는 읽기/쓰기 가능한 속성 요구
    func run() // 'run()'이라는 메서드 요구
}

class Man: Runnable { // 'Man' 클래스가 'Runnable' 프로토콜을 준수 ,adopt
    var x: Int = 1 // 'x' 속성을 구현, 기본값 1로 초기화,준수, conform
    
    func run() {print("Runnnn~~~~")}// 'run()' 메서드를 구현, 메서드가 호출되면 출력, 준수,conform
   
}

var kim: Man = Man() // 'Man' 클래스의 인스턴스 생성
kim.run() // 'kim'의 'run()' 메서드 호출, "Runnnn~~~~" 출력

프로토콜은 여러개가 올 수 있음

 

 

상속과 프로토콜을 사용한 간단한 예제

// 'Workable'이라는 프로토콜 정의
protocol Workable {
    func work() // 일하기 메서드 요구
}

// 기본 클래스 'Employee' 정의
class Employee: Workable {
    var name: String // 직원의 이름
    var salary: Double // 직원의 급여
    
    // 초기화 메서드
    init(name: String, salary: Double) {
        self.name = name // 이름 초기화
        self.salary = salary // 급여 초기화
    }
    
    // 프로토콜의 'work()' 메서드 구현
    func work() {
        print("\(name) is working.") // 직원이 일하고 있음을 출력
    }
}

// 'Manager' 클래스가 'Employee' 클래스를 상속
class Manager: Employee {
    // 사장만의 고유 메서드
    func manage() {
        print("\(name) is managing the team.") // 사장이 팀을 관리하고 있음을 출력
    }
}

// 'PartTimeWorker' 클래스가 'Employee' 클래스를 상속
class PartTimeWorker: Employee {
    // 아르바이트생만의 고유 메서드
    func serve() {
        print("\(name) is serving customers.") // 아르바이트생이 고객을 서비스하고 있음을 출력
    }
}

// 사용 예: 'Manager' 인스턴스 생성
let boss = Manager(name: "사장님", salary: 5000)
boss.work() // "사장님 is working." 출력
boss.manage() // "사장님 is managing the team." 출력

// 사용 예: 'PartTimeWorker' 인스턴스 생성
let worker = PartTimeWorker(name: "아르바이트생", salary: 2000)
worker.work() // "아르바이트생 is working." 출력
worker.serve() // "아르바이트생 is serving customers." 출력

 

'Swift' 카테고리의 다른 글

iOS프로그래밍 실무 6주차  (0) 2025.04.09
iOS프로그래밍 실무 5주차  (0) 2025.04.02
iOS프로그래밍 실무 3주차  (0) 2025.03.19
iOS 프로그래밍 실무 2주차  (0) 2025.03.17
iOS 프로그래밍 실무 1주차  (0) 2025.03.05

+ Recent posts