Skip to content

Files

Latest commit

b5f1832 ยท Mar 13, 2024

History

History

iOS

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Mar 13, 2024

iOS

๋‹จ์ถ•ํ‚ค

  • control + I: ์ž๋™์œผ๋กœ ์ค„๋งž์ถ”๊ธฐ
  • command + shift + y: ์ฝ˜์†” ์—…๋‹ค์šด

import Foundation?

  • Objective-C ์–ธ์–ด์™€ ๊ด€๋ จ๋œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.
  • ์ปฌ๋ ‰์…˜ NSArray, NSMutableArray, NSDictionary, NSSet ๋“ฑ์„ ์ œ๊ณตํ•œ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋‚˜ ๋‚ ์งœ ๊ด€๋ จ NSData, NSDate ๋“ฑ์„ ์ œ๊ณตํ•œ๋‹ค.
  • ์™ธ์šธ ํ•„์š”๋Š” ์—†์Œ!

์ƒ์†๊ด€๊ณ„์—์„œ ์ƒ์„ฑ์ž ์œ„์ž„ ๊ทœ์น™

  1. ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ์—…(Delegate Up)

    ์„œ๋ธŒ ํด๋ž˜์Šค์˜ ์ง€์ • ์ƒ์„ฑ์ž๋Š” ์Šˆํผ ํด๋ž˜์Šค์˜ ์ง€์ •์ƒ์„ฑ์ž๋ฅผ ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœํ•ด์•ผํ•œ๋‹ค.


  1. ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ์–ดํฌ๋กœ์Šค(Delegate across)

    ํŽธ์˜ ์ƒ์„ฑ์ž๋Š” ๋™์ผํ•œ ํด๋ž˜์Šค์—์„œ ๋‹ค๋ฅธ ํŽธ์˜ ์ƒ์„ฑ์ž ๋˜๋Š” ์ง€์ • ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ด์•ผํ•˜๊ณ  ๊ถ๊ทน์ ์œผ๋กœ๋Š” ์ง€์ • ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ด์•ผํ•œ๋‹ค.


ํ”„๋กœํ† ์ฝœ ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

์• ํ”Œ์ด ์ตœ์ดˆ๋กœ ํ”„๋กœํ† ์ฝœ ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„์„ ์ œ์‹œํ–ˆ๋‹ค.


ํด๋ž˜์Šค์™€ ์ƒ์†์˜ ๋‹จ์ 

  • ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋งŒ ์ƒ์†์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ํ•˜์œ„ํด๋ž˜์Šค๋Š” ์ƒ์œ„ํด๋ž˜์Šค์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ผ๊ฐˆ ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.
  • ํด๋ž˜์Šค์—์„œ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.

ํ•˜์ง€๋งŒ ํ”„๋กœํ† ์ฝœ ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ผ ๊ฒฝ์šฐ?

  • ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ”„๋กœํ† ์ฝœ ์ฑ„ํƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. โ†’ ์กฐํ•ฉ์˜ ์žฅ์ ์„ ์‚ด๋ ค์„œ ๊ตฌ์„ฑ/์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ์— ๋Œ€ํ•œ ํŠน์ • ์š”๊ตฌ์‚ฌํ•ญ์ด ์—†๋‹ค. โ†’ ํ•„์š”ํ•œ ์†์„ฑ/๋ฉ”์„œ๋“œ๋งŒ ์ฑ„ํƒํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ชจ๋“  ํƒ€์ž…์—์„œ ์ฑ„ํƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. โ†’ ํ™œ์šฉ์„ฑ์ด ๋Š˜์–ด๋‚œ๋‹ค.

Method Dispatch

์Šค์œ„ํ”„ํŠธ๊ฐ€ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ ์„ธ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

  1. Direct Dispatch

    ์ปดํŒŒ์ผ ์‹œ์ ์— ์ฝ”๋“œ ์ž์ฒด์— ํ•จ์ˆ˜์˜ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ ์‚ฝ์ž… ๋˜๋Š” ํ•จ์ˆ˜์˜ ๋ช…๋ น ์ฝ”๋“œ๋ฅผ ํ•ด๋‹น ์œ„์น˜์— ์ฝ”๋“œ๋ฅผ ์‹ฌ๋Š”๋ฐฉ์‹์ด๋‹ค. ์„ธ ๋ฐฉ์‹์ค‘์— ๊ฐ€์žฅ ๋น ๋ฅด์ง€๋งŒ value type์ธ ๊ตฌ์กฐ์ฒด์™€ ์—ด๊ฑฐํ˜•์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์†๊ณผ ๋‹คํ˜•์„ฑ์˜ ์žฅ์ ์„ ๋ˆ„๋ฆด ์ˆ˜ ์—†๋‹ค.


  1. Table Dispatch

    ํ•จ์ˆ˜์˜ ํฌ์ธํ„ฐ๋ฅผ ๋ฐฐ์—ด์— ๋ณด๊ด€ ํ›„ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ์„ธ ๋ฐฉ์‹์ค‘์— ๋‘๋ฒˆ์งธ๋กœ ๋น ๋ฅด๋ฉฐ ํด๋ž˜์Šค์™€ ํ”„๋กœํ† ์ฝœ์—์„œ ์‚ฌ์šฉํ•œ๋‹ค. ํด๋ž˜์Šค๋Š” Virtual Table, ํ”„๋กœํ† ์ฝœ์€ Witenss Table์„ ์‚ฌ์šฉํ•œ๋‹ค.


  1. Message Dispatch

    ์ƒ์†๊ตฌ์กฐ๋ฅผ ๋ชจ๋‘ ํ›‘์€ ํ›„์— ์‹คํ–‰ํ•  ๋ฉ”์„œ๋“œ๋ฅผ ๊ฒฝ์ •ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ์„ธ ๋ฐฉ์‹์ค‘์— ๊ฐ€์žฅ ๋А๋ฆฌ๋ฉฐ ์ฃผ๋กœ Objective-C ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉํ•œ๋‹ค.


ARC: Automatic Reference Counting

ARC๋Š” ์Šค์œ„ํ”„ํŠธ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ชจ๋ธ์ด๋‹ค. Automatic Reference Counting์˜ ์ค„์ž„๋ง๋กœ, ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ์ฐธ์กฐ์˜ ์ˆซ์ž๋ฅผ ์„ผ๋‹ค. ๋งŒ์•ฝ ์ˆ˜๋™์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์งœ์•ผํ•œ๋‹ค.

class Point {
	var refCount: Int           // ์ฐธ์กฐ ์ˆซ์ž๋ฅผ ์„ธ์ฃผ๋Š” ๋ณ€์ˆ˜
	var x, y: Double
	func draw() { ... }
}

let point1 = Point(x: 0, y: 0) // +1, refCount = 1
let point2 = point1 
retain(point2)                 // +1, refCount = 2

point2.x = 5

release(point1)                // -1, refCount = 1
release(point2)                // -1, refCount = 0 -> ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ํ•ด์ œ

retain() โ†’ Reference Counting์˜ ์ˆซ์ž๋ฅผ ํ•˜๋‚˜ ์˜ฌ๋ฆฐ๋‹ค.

release() โ†’ Reference Counting์˜ ์ˆซ์ž๋ฅผ ํ•˜๋‚˜ ๋‚ด๋ฆฐ๋‹ค.

๋”ฐ๋ผ์„œ, Referece Counting์ด 0์ด ๋˜๋Š” ์ˆœ๊ฐ„ ๋ฉ”๋ชจ๋ฆฌํ• ๋‹น์„ ํ•ด์ œ ํ•œ๋‹ค. ์Šค์œ„ํ”„ํŠธ์— ARC๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๋Š” retain, release๋ฅผ ์‹ ๊ฒฝ ์•ˆ์จ๋„ ์ปดํŒŒ์ผํ•  ๋•Œ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•œ๋‹ค.


๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด

๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด์€ ๊ฐ์ฒด ๋‘ ๊ฐœ๊ฐ€ ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์–ด, ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ๊ฐ€ ์•ˆ๋˜๊ณ  ํ•ด์ œ ์‹œํ‚ฌ ๋ฐฉ๋ฒ•๋„ ์—†๋Š” ํ˜„์ƒ์ด๋‹ค.

class Dog {
	var name: String
	var owner: Person?

	init(name: String) {
		self.name = name
	}

	deinit { // ์†Œ๋ฉธ์ž
		print("\(name) ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ")
	}
}

class Person {
	var name: String
	var pet: Dog?
	
	init(name: String) {
		self.name = name
	}

	deinit {
		print("\(name) ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ")
	}
}

var bori: Dog? = Dog(name: "๋ณด๋ฆฌ")
var gildong: Person? = Person(name: "ํ™๊ธธ๋™")

bori?.owner = gildong
gildon?.pet = bori
// --> ๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด ๋ฐœ์ƒ

bori = nil    // ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ๋ถˆ๊ฐ€
gildong = nil // ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ๋ถˆ๊ฐ€

์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด โ€œ๋ณด๋ฆฌโ€์˜ ์ฃผ์ธ์€ โ€œ๊ธธ๋™โ€์ด๊ณ  โ€œ๊ธธ๋™โ€์˜ ์• ์™„๋™๋ฌผ์€ โ€œ๋ณด๋ฆฌโ€์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋‘ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์–ด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.


๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์˜ ํ•ด๊ฒฐ๋ฐฉ์•ˆ 2๊ฐ€์ง€

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์˜ ํ•ด๊ฒฐ๋ฐฉ์•ˆ 2๊ฐ€์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ณตํ†ต์ ์œผ๋กœ Referece Counting ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๋Š”๋‹ค.

  1. ์•ฝํ•œ ์ฐธ์กฐ(Weak Reference)

    ๋‹จ์ˆœํžˆ ์•ž์— weak ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

    class Dog {
    	var name: String
    	weak var owner: Person?
    
    	init(name: String) {
    		self.name = name
    	}
    
    	deinit { // ์†Œ๋ฉธ์ž
    		print("\(name) ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ")
    	}
    }
    
    class Person {
    	var name: String
    	weak var pet: Dog?
    	
    	init(name: String) {
    		self.name = name
    	}
    
    	deinit {
    		print("\(name) ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ")
    	}
    }
    
    var bori: Dog? = Dog(name: "๋ณด๋ฆฌ")
    var gildong: Person? = Person(name: "ํ™๊ธธ๋™")
    
    // ๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ
    bori?.owner = gildong
    gildon?.pet = bori
    
    bori = nil    // print("๋ณด๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ")
    gildong = nil // print("ํ™๊ธธ๋™ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ")

    ์•ฝํ•œ ์ฐธ์กฐ์˜ ๊ฒฝ์šฐ, ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์‚ฌ๋ผ์ง€๋ฉด, nil๋กœ ์ดˆ๊ธฐํ™”๊ฐ€ ๋˜์–ด์žˆ๋‹ค. nil์„ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— weak let์ด๋‚˜ Non-Optional ์„ ์–ธ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ๋”ฐ๋ผ์„œ ์†Œ์œ ์ž์— ๋น„ํ•ด ์งง์€ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง„ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ• ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.


  1. ๋น„์†Œ์œ  ์ฐธ์กฐ(Unowned Referece)

    ์•ฝํ•œ ์ฐธ์กฐ์™€ ๋˜‘๊ฐ™์ด ์•ž์— unowned ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์ธ๋‹ค.

    class Dog {
    	var name: String
    	unowned var owner: Person?
    
    	init(name: String) {
    		self.name = name
    	}
    
    	deinit { // ์†Œ๋ฉธ์ž
    		print("\(name) ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ")
    	}
    }
    
    class Person {
    	var name: String
    	unowned var pet: Dog?
    	
    	init(name: String) {
    		self.name = name
    	}
    
    	deinit {
    		print("\(name) ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ")
    	}
    }
    
    var bori: Dog? = Dog(name: "๋ณด๋ฆฌ")
    var gildong: Person? = Person(name: "ํ™๊ธธ๋™")
    
    // ๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ
    bori?.owner = gildong
    gildon?.pet = bori
    
    bori = nil    // print("๋ณด๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ")
    gildong = nil // print("ํ™๊ธธ๋™ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ")

    ์•ฝํ•œ ์ฐธ์กฐ์™€ ๋‹ค๋ฅด๊ฒŒ ๋น„์†Œ์œ  ์ฐธ์กฐ๋Š” ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์‚ฌ๋ผ์ง€๋ฉด, nil๋กœ ์ดˆ๊ธฐํ™” ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ์†Œ์œ ์ž ๋ณด๋‹ค ์ธ์Šคํ„ด์Šค์˜ ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ๋” ๊ธธ๊ฑฐ๋‚˜, ๊ฐ™์€ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•œ๋‹ค.

    ์œ„ ์˜ˆ์ œ๋“ค์„ ๋ดค๋“ฏ์ด, unowned ์‚ฌ์šฉ์‹œ์—๋Š” ํ•œ๋ฒˆ ๋” ๊ณ ๋ คํ•  ๊ฒƒ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์‹ค์ œ๋กœ๋Š” weak ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์•ฝํ•œ ์ฐธ์กฐ๋ฅผ ํ”„๋กœ์ ํŠธ์—์„œ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค.


์ƒ๋ช…์ฃผ๊ธฐ(Life Cycle)

  • viewDidLoad - ์Šคํ† ๋ฆฌ๋ณด๋“œ์ƒ์˜ ๋ทฐ๋“ค๊ณผ์˜ ์—ฐ๊ฒฐ์ด ๋๋‚œ ์‹œ์ 
  • viewWillAppear - ์‹ค์ œ ์Šคํฌ๋ฆฐ์— ๋ทฐ๊ฐ€ ๋‚˜ํƒ€๋‚˜๊ธฐ ์ „์— ํ˜ธ์ถœ
  • viewDidAppear - ์‹ค์ œ ์Šคํฌ๋ฆฐ์— ๋ทฐ๊ฐ€ ๋‚˜ํƒ€๋‚œ ํ›„์— ํ˜ธ์ถœ
  • viewWillDisappear - ์‹ค์ œ ์Šคํฌ๋ฆฐ์— ๋ทฐ๊ฐ€ ์‚ฌ๋ผ์ง€๊ธฐ ์ „์— ํ˜ธ์ถœ
  • viewDidDisappear - ์‹ค์ œ ์Šคํฌ๋ฆฐ์— ๋ทฐ๊ฐ€ ์‚ฌ๋ผ์ง„ ํ›„์— ํ˜ธ์ถœ