iOS 프로그래밍 5주차

2024. 10. 13. 20:53📱 모바일 프로그래밍/iOS 프로그래밍 기초

함수와 메서드(method)

 

함수과 함수 자료형(type)

Q: iOS테이블뷰에서 많이 사용하는 메서드를 많이 사용하는 순서대로 나열하고 예를 들어 기능을 설명하고,

     전체 메서드 이름과 메서드 자료형을 알려줘

1. tableView(_:numberOfRowsInSection:)

  • 설명: 특정 섹션에 몇 개의 셀이 포함될지 설정합니다. 각 섹션별로 행의 개수를 반환하는 메서드로, 데이터 소스의 항목 수에 따라 설정됩니다.
  • 메서드 시그니처:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
  • 자료형: Int (반환값)

2. tableView(_:cellForRowAt:)

  • 설명: 각 행의 셀을 구성하고 반환합니다. 여기서 셀의 내용을 설정하고, 셀의 재사용을 통해 메모리 효율을 높입니다.
  • 메서드 시그니처:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
  • 자료형: UITableViewCell (반환값)

3. numberOfSections(in:)

  • 설명: 테이블 뷰에 섹션이 몇 개인지 반환합니다. 대부분의 경우 섹션이 하나일 때는 기본값으로 1을 반환합니다.
  • 메서드 시그니처:
func numberOfSections(in tableView: UITableView) -> Int

 

  • 자료형: Int (반환값)

4. tableView(_:heightForRowAt:)

  • 설명: 특정 행의 높이를 반환합니다. 테이블 뷰의 행 높이를 동적으로 조정해야 할 때 사용합니다.
  • 메서드 시그니처:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
  • 자료형: CGFloat (반환값)

5. tableView(_:didSelectRowAt:)

  • 설명: 특정 행이 선택되었을 때 호출되는 메서드로, 선택된 셀에 대한 액션을 정의할 수 있습니다.
  • 메서드 시그니처:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
  • 자료형: Void (반환값 없음)

6. tableView(_:titleForHeaderInSection:)

  • 설명: 특정 섹션의 헤더 타이틀을 반환합니다. 섹션별로 헤더 텍스트를 설정하는 데 사용됩니다.
  • 메서드 시그니처:
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
  • 자료형: String? (옵셔널 문자열, 반환값)

optional binding

var x : Int?
x = 10
if let xx = x {   // 옵셔널 변수 x가 값(10)이 있으므로 언래핑해서 일반상수 xx에 대입하고 if문 실행
    print(x, xx)
}
else {
    print("nil")
}
var x1 : Int?
if let xx = x1 {   // 옵셔널 변수 x1 값이 없어서 if문의 조건이 거짓이 되어 if문 실행하지 않고 else로 감
    print(xx)
}
else {
    print("nil")
}
// 출력
// Optional(10) 10
// nil

if let x = x 라고 써도 됨

Swift 5.7부터는 if let x라고 써도 됨 - short form of if-let to the Optional Binding

 

guard문(조건식이 거짓이면 실행)

표현식이 거짓(false)으로 판단될 경우에 수행될 else절을 반드시 포함해야함

guard <불리언 표현식> else {
// 표현식이 거짓일 경우에 실행될 코드
<코드 블럭을 빠져 나갈 구문>
}
//표현식이 참일 경우에 실행되는 코드는 이곳에 위치

기본적으로 특정 조건에 맞지 않을 경우에 현재의  함수나 반복문에서 빠져 나갈 수 있도록 하는 '조기 출구(early exit)' 전략을 제공

 

guard ~ let의 활용

var x = 1
while true {
    guard x < 5 else { break }  // 조건(x < 5)이 거짓일 때 실행(break)
    print(x)    // 1 2 3 4, 조건(x < 5)이 참일 때 실행
    x = x + 1
}

 

guard let ~ else로 옵셔널 바인딩

func multiplyByTen(value: Int?) {
    guard let number = value else {   // 조건식이 거짓(nil)일 때 else 블록 사용
        print("nil")
        return
    }
    print(number * 10)
}

multiplyByTen(value: 3)  
// 출력: 30, value에 3이 전달돼 print(number * 10)이 실행되어 10이 출력

multiplyByTen(value: nil) 
// 출력: nil, value에 nil이 전달돼 guard문이 충족되지 않아 else 블록 사용

multiplyByTen(value: 10)  
// 출력: 100, value에 10이 전달돼 print(number * 10)이 실행되어 10이 출력

 

언래핑된 number 변수를 guard문 밖에 있는 코드가 사용할 수 있다.

 

if ~ let vs. guard ~ let: guard let이 소스 보기가 편해요

func printName(firstName:String, lastName:String?) {
    // if let
    if let lName = lastName {   // lastName이 nil이 아니면
        print(lName, firstName)
    }
    else {
        print("성이 없네요")
    }
}

printName(firstName: "길동", lastName: "홍")
// 홍 길동: lastName이 홍이 전달돼 if문 실행
printName(firstName: "길동", lastName: nil)
// 성이 없네요: lastName이 nil이 전달돼 else문 실행
func printName(firstName:String, lastName:String?) {   
    // guard let
    guard let lName = lastName else {   // lastName이 nil이면
        print("성이 없네요!")
        return  // early exit
    }
    print(lName, firstName)
}

printName(firstName: "길동", lastName: "홍")
// 홍 길동: lastName이 홍이 전달돼 print(lName, firstName) 출력
printName(firstName: "길동", lastName: nil)
// 성이 없네요!: lastName이 nil전달돼 print("성이 없네요!") 출력

 

 

디폴트 매개변수(아규먼트) 정의하기

// 이름이 인자로 전달되지 않을 경우에 디폴트로 "길동"이라는 문자열이 사용되도록 함
func sayHello(count: Int, name: String = "길동") -> String {
    return ("\(name), 너의 번호는 \(count)")
}

// 이름을 가지고 함수를 호출하면 argument를 사용
var message = sayHello(count: 10, name: "소프트") // 소프트, 너의 번호는 10

// 이름을 전달하지 않고도 호출 가능하며 디폴트로 "길동" 사용
message = sayHello(count: 100)
print(message) // 길동, 너의 번호는 100

argument로 전달하는 값이 없는 경우, 디폴트 매개변수 값을 사용

함수를 선언할 때 매개변수에 디폴트 값을 할당

 

함수로부터 여러 개의 결과 반환하기

func converter(length: Float) -> (yards: Float, centimeters: Float, meters: Float) {
    let yards = length * 0.0277778
    let centimeters = length * 2.54
    let meters = length * 0.0254
    return (yards, centimeters, meters)
}

var lengthTuple = converter(length: 10)
print(lengthTuple)  // (yards: 0.277778, centimeters: 25.4, meters: 0.254)
print(lengthTuple.yards)    // 0.277778, 10 * 0.0277778
print(lengthTuple.centimeters)  // 25.4, 10 * 2.54
print(lengthTuple.meters)   // 0.254, 10 * 0.0254

함수는 여러 결과 값들을 튜플로 감싸서 반환할 수 있음

인치 단위의 수를 매개변수로 받아 야드, 센티미터, 미터로 변환하고 이 세 개의 값을 하나의 튜플에 넣어 반환

 

2개의 점수를 입력받아 가감제 리턴

import Foundation

func sss(x: Int, y: Int) -> (sum: Int, sub: Int, div: Double, mul: Int, rem: Int) {
    let sum = x + y
    let sub = x - y
    let div = Double(x) / Double(y) // 같은 자료형만 연산 가능
    let mul = x * y
    let rem = x % y
    return (sum, sub, div, mul, rem)
}
var result = sss(x: 10, y: 3)
print(result.sum)   // 13, 10 + 3
print(result.sub)   // 7, 10 - 3
print(result.div)   // 3.3333333333333335, 10 / 3
print(result.mul)   // 30
print(result.rem)   // 1
print(String(format: "%.3f", result.div))   // 3.333, 소수점 3자리에서 반올림
print(type(of:sss)) // (Int, Int) -> (sum: Int, sub: Int, div: Double, mul: Int, rem: Int)

 

가변 매개변수(variadic parameter)

func displayStrings(strings: String...) {
    for string in strings {   // 전달받은 문자열을 하나씩 돌며 print(string)을 통해 출력
        print(string)
    }
}
displayStrings(strings: "일", "이", "삼", "사")
// 일
// 이
// 삼
// 사
displayStrings(strings: "one", "two")
// one
// two
displayStrings(strings: "one", "two", "a", "b", "c")
// one
// two
// a
// b
// c

함수가 가변 매개변수를 받는다는 것을 가리키기 위해서 세 개의 점(...)을 사용

지정되지 않은 개수의 String값을 매개변수로 받아서 콘솔에 출력

func add(nums: Int...)
{
    var sum: Int = 0
    for num in nums {
        sum += num
    }
    print(sum)
}
add(nums: 1,1,1,1,1,1,1)
add(nums: 1,2,3,4,5)

임의의 개수의 정수 값의 합을 출력하는 함수

 

inout매개변수: call by address 구현

함수가 값을 반환한 후에도 매개변수에 일어난 변화를 유지하려면,

함수의 선언부에서 매개변수를 입출력 매개변수(in-out parameter)로 선언해야함

var myValue = 10
func doubleValue(value: inout Int) -> Int { // 호출할 때 주소값을 넘겨야 함
    value += value   //  함수 내부에서 value에 자신의 값을 더해 두 배로 만들고 이 값을 반환
    return(value)
}
print(myValue)  // 10
print(doubleValue(value: &myValue)) 
// 20, doubleValue 함수를 호출하면서 &myValue를 전달. 함수 내부에서 value는 두 배가 되어 20이 됨. 이 값이 반환
print(myValue)  // 20

call by address하고 싶은 매개변수의 자료형 앞에 inout 씀

call by address하고 싶은 변수에 &붙여서 호출

 

Swift 문자열 서식(swift string format 자리수)

import Foundation

let weight = 60.0
let height = 170.0
let bmi = weight / (height*height*0.0001)   // kg/m*m
let shortenedBmi = String(format: "%.lf", bmi)

var body = ""
if bmi >= 40 {
    body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
    body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
    body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
    body = "정상"
} else {
    body = "저체중"
}

print("BMI:\(shortenedBmi), 판정:\(body)")

 

BMI를 판정하는 calcBMI() 함수 정의

import Foundation

func calcBMI(weight: Double, height: Double) -> String {
    let bmi = weight / (height*height*0.0001)   // kg/m*m
    let shortenedBmi = String(format: "%.lf", bmi)
    
    var body = ""
    if bmi >= 40 {
        body = "3단계 비만"
    } else if bmi >= 30 && bmi < 40 {
        body = "2단계 비만"
    } else if bmi >= 25 && bmi < 30 {
        body = "1단계 비만"
    } else if bmi >= 18.5 && bmi < 25 {
        body = "정상"
    } else {
        body = "저체중"
    }
    return "BMI:\(shortenedBmi), 판정:\(body)"
}
print(calcBMI(weight: 48.5, height: 171.9))

 

if ~ else를 switch ~ case로

import Foundation

func calcBMI(weight: Double, height: Double) {
    let bmi = weight / (height*height*0.0001)   // kg/m*m
    let shortenedBmi = String(format: "%.lf", bmi)
    
    switch bmi {
        case 0.0..<18.5:
            print("BMI:\(shortenedBmi), 판정:저체중")
        case 18.5..<25.5:
            print("BMI:\(shortenedBmi), 판정:정상")
        case 25.0..<30.0:
            print("BMI:\(shortenedBmi), 판정:1단계 비만")
        case 30.0..<40.0:
            print("BMI:\(shortenedBmi), 판정:2단계 비만")
        default:
            print("BMI:\(shortenedBmi), 판정:3단계 비만")
    }
}
calcBMI(weight: 48.5, height: 171.9)

 

switch ~ case + 판정 결과 리턴하는 함수

import Foundation

func calcBMI(weight: Double, height: Double) -> String {
    let bmi = weight / (height*height*0.0001)   // kg/m*m
    let shortenedBmi = String(format: "%.lf", bmi)
    
    var body = ""
    switch bmi {
        case 0.0..<18.5:
        body = "저체중"
        case 18.5..<25.5:
        body = "정상"
        case 25.0..<30.0:
        body = "1단계 비만"
        case 30.0..<40.0:
        body = "2단계 비만"
        default:
        body = "3단계 비만"
    }
    return "BMI:\(shortenedBmi), 판정:\(body)"
}
print(calcBMI(weight: 48.5, height: 171.9))

 

 

1급 객체(first class object)

1급 시민(first class citizen)

 

 

1급 객체(first class object) 또는 1급 시민(first class citizen)

Swift의 함수는 1급 객체이다.

1급 객체(first class object) 또는 1급 시민(first class citizen)

다음 조건을 충족하는 객체를 1급 객체라 한다

   1) 변수에 저장할 수 있다

   2) 매개변수로 전달할 수 있다

   3) 리턴값으로 사용할 수 있다

 

함수 : 일급 객체 실습

func up(num: Int) -> Int {
    return num + 1
}
func down(num: Int) -> Int {
    return num - 1
}
// 1) 변수에 저장할 수 있다
let toUp = up
print(up(num: 10))  // 11
print(toUp(10))     // 11
let toDown = down
print(down(num: 10))    //9
print(toDown(10))   //9

// 2) 매개변수로 전달할 수 있다
func upDown(Fun: (Int) -> Int, value: Int) {
    let result = Fun(value)
    print("결과 = \(result)")
}
upDown(Fun: toUp, value: 10)    // toUp(10), 11
upDown(Fun: toDown, value: 10)  // toDown(10), 9

// 3) 리턴값으로 사용할 수 있다
func decideFun(x: Bool) -> (Int) -> Int {
              // 매개벼수형    리턴형이 함수형
    if x {
        return toUp
    } else {
        return toDown
    }
}
let r = decideFun(x: true)
print(type(of: r))  // (Int) -> Int
print(r(10))    // 11

1) Swift는 함수를 데이터 타입처럼 처리할 수 있음

    함수를 호출하려면 원래의 함수 이름 대신에 상수 이름을 이용하여 호출 가능

 

 

클로저(Closure)

클로저 표현식

클로저: 특정 작업(함수)과 그 작업이 일어난 곳(환경 또는 상태)을 모두 기억하고 있는 도구

익명함수

클로저 표현식은 독립적인 코드 블록

{(<매개변수 이름>: <매개변수 타입>, ...) -> <반환 타입> in
   // 클로저 표현식 코드
}
func add(x: Int, y: Int) -> Int {
    return x + y
}
print(add(x: 10, y: 20))
print(type(of: add))    // (Int, Int) -> Int


// 클로저
let add1 = {(x: Int, y: Int) -> Int in
    return x + y
}
print(add1(10, 20))
print(type(of: add1))   // (Int, Int) -> Int

 

두 개의 정수 매개변수를 받아서 정수 결과 값을 반환 

func mul(val1: Int, val2: Int) -> Int
{
    return val1 * val2
}
let result = mul(val1: 10, val2: 20)
print(result)   // 200

// 클로저
let multiply = {(val1: Int, val2: Int) -> Int in
                    // 매개변수             리턴형
    return val1 * val2
}   // multiply 자료형 (Int, Int) -> Int
let result2 = multiply(10, 20)  // 상수를 함수처럼 호출, 200
print(result2)

 

출처: iOS 프로그래밍 강의 자료

'📱 모바일 프로그래밍 > iOS 프로그래밍 기초' 카테고리의 다른 글

iOS 프로그래밍 9주차  (0) 2024.10.30
iOS 프로그래밍 6주차  (0) 2024.10.16
iOS 프로그래밍 4주차  (0) 2024.10.07
iOS 프로그래밍 3주차  (0) 2024.09.25
iOS 프로그래밍 2주차  (0) 2024.09.11