iOS 4주차 수업 내용 및 수업 후 과제

2025. 9. 23. 15:17iOS 기초/수업 내용 및 수업 후 과제

반응형

# 배열 항목 접근 

let names = ["A", "B", "C", "D"]

for name in names {
    print(name)
}

 

 

# dictionary의 항목 접근

// Dictionary: 동물 이름을 키(key)로, 다리 개수를 값(value)으로 저장
let numberOfLegs = [
    "거미": 8,
    "개미": 6,
    "개": 4
]

// 딕셔너리를 반복하면서 각 동물의 이름과 다리 개수를 출력
for (animalName, legCount) in numberOfLegs {
    print("\(animalName)는 \(legCount)개 다리")
}

 

 

# 반복문에서 빠져나오기

// ERROR
for i in 1..<10 {
    if i > 5 break
    //중요!! 에러 수정 과제: error: expected '{' after 'if' condition
    //if 문 다음의 실행 코드가 한 줄이라도 괄호({})를 필수적으로 사용
    print(i)
}
for i in 1..<10 {
    if i > 5 {
        break
    }
    print(i)
}

* Swift에선 한 줄이어도 중괄호({ })를 반드시 열고 닫아야 함

 

# if문 조건에서 콤마: 조건나열(condition-list)

var x = 1
var y = 2

if x == 1 && y == 2 { // 논리식이 둘 다 참일 때
    print(x, y)
}

if x == 1, y == 2 { // 조건이 둘 다 참일 때, 두 조건을 콤마로 연결한 condition-list
    print(x, y)
}

var a: Int? = 1
var b: Int? = 2

print(a, b)

if let a1 = a, let b1 = b {
    print(a1, b1)
}

// if let a1 = a && let b1 = b { // error: expected ',' joining parts of a multi-clause condition
//     print(a1, b1)
// }

 

- 조건식이 둘 다 참일 때, &&를 쓰지 않고 콤마(,)를 사용해 연결함

for 초기화; 조건식; 증감식 {
// 실행될 구문
}
for var i = 0; i < 10; i+=1 { // for i in 0..<10 로 수정해야 함
print(i)
} //error: C-style for statement has been removed in Swift 3

 

# switch-case문

var value = 0  // 변수 value에 0을 할당

switch (value) {  // value 변수의 값을 기준으로 여러 경우를 검사
case 0:
    print("영")  // value가 0일 때 출력
case 1:
    print("일")  // value가 1일 때 출력
case 2:
    print("이")  // value가 2일 때 출력
case 3:
    print("삼")  // value가 3일 때 출력
default:
    print("4이상")  // 위 모든 case에 해당하지 않는 값일 때 출력
}
let anotherCharacter: Character = "a"

switch anotherCharacter {
case "a": // 오류, 각 case에는 실행문이 한 문장이라도 있어야 함
    // 실행문이 없어서 에러 발생
    break
case "A":
    print("A글자")
default:
    print("A글자 아님")
}

- switch 문에서는 각 케이스 끝에 자동으로 break가 포함되어 있어서, 따로 break를 써주지 않아도 자동으로 그 케이스만 실행되고 switch를 빠져나감

- 각 case에는 실행문이 한 문장이라도  있어야 함

switch-case에서 where절 사용하기
 where절을 switch case에 부가적인 조건을 추가하기 위하여 사용
 값이 속하는 범위뿐만 아니라 그 숫자가 홀수인지 짝수인지도 검사 var temperature = 60
 switch (temperature)
 {
 case 0...49 where temperature % 2 == 0:
   print("Cold and even")
 case 50...79 where temperature % 2 == 0:
print("Warm and even")
case 80...110 where temperature % 2 == 0:
   print("Hot and even")
 default:
   print("Temperature out of range or odd")
 }
과제 : where절 예제 하나 만들기
switch, catch, while, guard, for 등에서 사용 가능

 

func sayHello(){
    print("Hello");
}
//sayHello()
print(type(of: sayHello)) // () -> ()

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

func add(xx x: Int, yy y: Int) -> Int { return(x+y)
}
add(xx:1, yy:2)

var x : Int = 10

print(type(of: add)) //(Int, Int) -> Int


**parameter(파라미터)**와 **argument(아규먼트)**는 헷갈리기 쉬운 개념이지만, 아주 쉽게 설명해볼게요. 😄


🍱 비유로 쉽게 이해하기

📦 파라미터(parameter)는 빈 도시락 통

  • 함수가 “받을 준비”를 하고 있는 빈 그릇이야.
  • 함수 선언할 때 "이런 걸 받을게!" 라고 미리 적어두는 형식적인 이름이야.

🍙 아규먼트(argument)는 도시락 안에 실제로 넣는 음식

  • 함수를 호출(call)할 때 실제로 넣어주는 이야.
  • 이 값이 빈 그릇(파라미터) 안에 담겨서 함수로 전달돼.

🔧 코드로 예를 들면:

void sayHello(char* name) {
    printf("Hello, %s!\n", name);
}
  • 여기서 name 👉 parameter (형식적인 이름)
sayHello("Alice");
  • 여기서 "Alice" 👉 argument (실제 전달되는 값)

🧠 정리

구분 설명 예시

Parameter (파라미터) 함수가 받을 이름만 미리 정해둠 void greet(int age)에서 age
Argument (아규먼트) 함수 호출할 때 실제로 전달하는 값 greet(20)에서 20

💡 한 줄 요약:

🔹 Parameter는 함수가 받겠다고 선언한 그릇의 이름
🔹 Argument는 함수 호출할 때 그 그릇에 담아주는 실제 값


원하는 만큼 더 쉽게 풀어줄 수도 있어요. 비유나 그림, 예제 더 원하면 알려줘요! 😊

# 자료형

func sayHello() {
    print("Hello")
}
// sayHello()
print(type(of: sayHello))  // () -> ()
// () -> () 는 '입력 매개변수가 없고 반환값도 없는 함수' 타입을 의미

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

print(type(of: add)) // (Int, Int) -> Int
// (Int, Int) -> Int 는 '두 개의 Int 값을 입력으로 받고, Int 값을 반환하는 함수' 타입을 의미

- 빈 괄호(( ))는 튜플임 

* 마음대로 지워선 안 됨!

func sayHello(){
    print("Hello");
}
//sayHello()
print(type(of: sayHello)) // () -> ()

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

func add(first x: Int, second y: Int) -> Int { return(x+y)
}
print(add(first : 1, second : 2))

출력결과
() -> ()
3

//외부 매개변수명 생략하면 내부 매개변수명이 외부 매개변수명까지 겸함

 

Swift에서 함수 선언할 때 매개변수 이름호출 방식에 따라 달라지는 부분을 4가지 함수 예제로 설명해볼게요. 😄


1. 기본 함수 - 매개변수 이름 없이 호출하는 함수

func sayHello() {
    print("Hello")
}
sayHello()
print(type(of: sayHello)) // () -> ()
  • 매개변수가 없고, 그냥 간단히 실행하는 함수예요.
  • sayHello() 호출할 때 매개변수 없음.
  • 타입은 () -> () (입력도 없고 출력도 없음)

2. 기본 매개변수 이름 사용 (외부 이름과 내부 이름이 같음)

func add(x: Int, y: Int) -> Int {
    return x + y
}
add(x: 1, y: 2)
print(type(of: add))
  • 함수 선언 시 x, y가 **매개변수 이름(parameter name)**이에요.
  • 호출할 때도 add(x:1, y:2) 처럼 외부 이름으로 사용.
  • 외부 이름과 내부 이름이 같아서 호출할 때도 이름을 꼭 써야 해요.
  • 타입은 (Int, Int) -> Int

3. 외부 이름과 내부 이름을 다르게 지정한 경우

func add(first x: Int, second y: Int) -> Int {
    return x + y
}
add(first: 1, second: 2)
  • first 와 second는 외부 이름 (함수 호출 시 쓰는 이름)
  • x, y는 함수 내부에서 사용하는 내부 이름
  • 호출 시에는 add(first: 1, second: 2) 처럼 외부 이름을 꼭 써야 합니다.
  • 이 방식은 호출 시 더 읽기 좋은 이름을 줄 때 많이 씁니다.

4. 언더스코어 _를 사용해 외부 이름 생략하기

func add(_ x: Int, _ y: Int) -> Int {
    return x + y
}
add(1, 2)
  • 매개변수 앞에 _를 붙이면 외부 이름을 생략할 수 있어요.
  • 그래서 호출할 때는 add(1, 2) 처럼 매개변수 이름 없이 바로 값을 넣으면 됩니다.
  • 간결한 호출이 필요할 때 유용합니다.

5. 혼합: 첫 번째 매개변수 외부 이름 생략, 두 번째는 사용

func add(_ x: Int, second y: Int) -> Int {
    return x + y
}
add(1, second: 2)
  • 첫 번째 매개변수는 외부 이름 없이 바로 값만 넣음 (_ x)
  • 두 번째 매개변수는 외부 이름 필요 (second y)
  • 호출 시는 add(1, second: 2) 처럼 첫 번째는 이름 없이, 두 번째는 이름과 함께 씁니다.

요약

함수 선언 호출 예시 설명

func sayHello() sayHello() 매개변수 없음
func add(x: Int, y: Int) add(x: 1, y: 2) 외부 이름 = 내부 이름
func add(first x: Int, second y: Int) add(first: 1, second: 2) 외부 이름과 내부 이름 다름
func add(_ x: Int, _ y: Int) add(1, 2) 외부 이름 생략
func add(_ x: Int, second y: Int) add(1, second: 2) 첫 번째 생략, 두 번째 외부 이름 사용
함수명과 함수 자료형

func sayHello(){
    print("Hello");
    print(#function) // 실행결과 
}
sayHello()
print(type(of: sayHello)) // () -> ()


실행결과
Hello
sayHello()
() -> ()


func sayHello(){
    print("Hello");
    print(#function)
}
sayHello()
print(type(of: sayHello)) // () -> ()

func add(x : Int, y : Int) -> Int {
    print(#function) // 실행결과 add(x:y:)
    return x+y
}
add(x: 1, y: 2)


func add(first x: Int, second y: Int) -> Int {
    print(#function) //실행결과 add(first:second:)
    return(x+y)
}
add(first : 1, second : 2)

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


func add(_ x: Int, second y: Int) -> Int {
    print(#function)// 실행결과 add(_:second:)
    // :의 매개변수 개수만큼 :을 찍어야한다
    return x+y
}
add(1, second : 2)
func tableView(
    _ tableView: UITableView,
    numberOfRowsInSection section: Int
) -> Int

함수명 : (UITableView, Int) -> Int
함수의 자료형 : tableView(_: numberOfRowsInSection section:)

 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 함수에 대해

**자료형(함수 시그니처)**과 함수 이름 구하는 방법을 차근차근 설명할게요.


1. 함수 시그니처 (자료형)

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
  • 첫 번째 매개변수
    • 외부 이름: _ (생략)
    • 내부 이름: tableView
    • 타입: UITableView
  • 두 번째 매개변수
    • 외부 이름: numberOfRowsInSection
    • 내부 이름: section
    • 타입: Int
  • 반환 타입
    • Int (특정 섹션에 들어갈 행(row)의 개수)

2. 함수 이름 구하는 방법

  • Swift 함수 이름은 함수명 + 모든 외부 매개변수 이름(단, _는 제외) 조합입니다.
  • 이 함수에서:
    • 함수명: tableView
    • 첫 매개변수 외부 이름: _ → 함수 이름에 포함 안 함
    • 두 번째 매개변수 외부 이름: numberOfRowsInSection → 함수 이름에 포함됨
  • 따라서 함수 이름은:
tableView(_:numberOfRowsInSection:)

정리

함수 시그니처 함수 이름 설명

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int tableView(_:numberOfRowsInSection:) 첫 번째 외부 이름 _는 생략, 두 번째는 포함

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


cellForRowAt 메서드의 자료형(함수 시그니처)과 함수 이름을 구하는 과정을 차근차근 설명해줄게요.


1. cellForRowAt 함수 시그니처 (자료형)

UITableViewDataSource 프로토콜에 정의된 필수 메서드 중 하나로, 테이블 뷰의 각 행에 표시할 셀을 반환하는 역할을 합니다.

Swift 함수 선언:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

각 매개변수와 반환 타입

매개변수 위치 이름 타입 설명

첫 번째 매개변수 _ tableView UITableView 호출된 테이블 뷰
두 번째 매개변수 cellForRowAt indexPath IndexPath 셀을 요구하는 위치 정보
반환 타입 - UITableViewCell 해당 위치에 표시할 셀 반환

2. 함수 이름 구하는 과정과 방법

Swift 함수의 함수 이름외부 매개변수 이름을 포함합니다.
즉, 함수 이름은 단순히 함수명 뿐 아니라 외부 매개변수 이름까지 합친 형태입니다.


예:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
  • 함수 이름:
    • 기본 함수명은 tableView
    • 외부 매개변수 이름을 포함하면 tableView(_:cellForRowAt:)가 됩니다.
  • 즉,
    • 첫 매개변수는 _ (외부 이름 생략) → 생략 가능
    • 두 번째 매개변수는 cellForRowAt (외부 이름 있음)

함수 이름을 구하는 방법 정리

  • 함수 선언 시 func 함수명(외부이름 내부이름: 타입, ...) 형태를 본다.
  • 함수 이름은 함수명 + 모든 외부 매개변수 이름 (생략된 _ 제외) 를 이어붙인 형태다.
  • 매개변수 외부 이름이 _이면 이름에서 제외.
  • 매개변수 외부 이름이 있으면 함수 이름에 포함.

적용해보면

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
  • 첫 매개변수 외부 이름 _ → 생략
  • 두 번째 매개변수 외부 이름 cellForRowAt → 포함

=> 함수 이름:

tableView(_:cellForRowAt:)

참고로 Objective-C에서는

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

함수 이름은 tableView:cellForRowAtIndexPath:입니다.

 

guard문

var x = 1
while true {
if x > 4 { break }
print(x) //1 2 3 4 
x=x+1
}

출력결과
1
2
3
4
위의 문장을 guard문으로 바꾸기


var x = 1
while true {
    guard x < 5 else { break }
    print(x) // 1 2 3 4
    x = x + 1
}
출력결과
1
2
3
4

if문은 조건이 참 인경우 실행,
guard문은 거짓일때 실행하는것
반드시 뒤에 else를 써야한다
func printName(firstName:String, lastName:String?){ // if let
    if let lName = lastName {
        print(lName,firstName)
    }
    else {
        print("성이 없네요!")
    }
}
printName(firstName: "길동", lastName:"홍");
printName(firstName: "길동", lastName:nil)

실행결과
홍 길동
성이 없네요!


guard문으로 쉽게 바꾸기
func printName(firstName:String, lastName:String?){ // guard let
    guard let lName = lastName else {print("성이없네요!");return}
    print(lName,firstName)
    // swift에서 guard~else문을 쓰면 지역변수 영향을 받지 않고 바깥에서도 실행이 가능하다.
}
printName(firstName: "길동", lastName:"홍");
printName(firstName: "길동", lastName:nil)

실행결과
홍 길동
성이 없네요!

guard~else문이 소스길이가 더 짧고 속도가 더 빠르다는 장점이 있다

 

if 문과 guard 문은 비슷해 보이지만 조건을 검사하는 방식과 역할이 좀 다릅니다.


요약

구분 역할 조건이 참일 때 조건이 거짓일 때 특징

if 문 조건이 참이면 코드 실행 실행 실행 안 함 자유롭게 사용 가능
guard 문 조건이 거짓이면 탈출(exit) 계속 실행 반드시 else 블록 실행 (종료 or 탈출) 함수나 루프에서 조기 탈출을 위해 많이 씀

예제 비교

if문 사용

var x = 1
while true {
    if x > 4 { break }
    print(x)
    x += 1
}
  • x > 4 가 일 때 break로 반복문 종료

guard문 사용

var x = 1
while true {
    guard x < 5 else { break }
    print(x)
    x += 1
}
  • x < 5 가 거짓이면 else 내부 코드 실행 → break로 종료
  • 조건이 참일 때는 guard 뒤 코드 계속 실행

왜 guard를 쓰는가?

  • guard문은 조건을 만족하지 않을 때 조기 종료를 강제하기 때문에 코드가 더 깔끔해지고
  • "조건을 만족할 때만 정상 동작" 한다는 의도를 명확하게 나타냅니다.