Skip to content

Latest commit

ย 

History

History
351 lines (251 loc) ยท 9.99 KB

Protocol.md

File metadata and controls

351 lines (251 loc) ยท 9.99 KB

Protocol

์‚ฌ์šฉํ•˜๋Š” ์ด์œ 


  • structure, enumeration, class์˜ ์ฒญ์‚ฌ์ง„ ์ œ๊ณต

Extension๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ๋•Œ

  • Protocol์˜ ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Protocol์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

    1. ex) A ํด๋ž˜์Šค๊ฐ€ B ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅธ๋‹ค.
    2. Bํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•œ๋‹ค.
    3. Aํด๋ž˜์Šค๋Š” ํ™•์žฅํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    // ๋” ์Šค์œ„ํ”„ํŠธ ์Šค๋Ÿฌ์šด ํ‘œํ˜„
    extension CustomStringConvertible where Self == KimFamily {
    	var description: String { return "kim" }
    }
    
    // ๋” ์ œ๋„ค๋ฆญํ•œ ํ‘œํ˜„
    extension Sequence where Self.Iterator.Element == KimFaily {
    	// ....
    }
  • ์•ˆ๋˜๋Š” ๊ฒƒโ€ผ๏ธย : ์ƒ์†

    ๋‹ค๋ฅธ ํ”„๋กœํ† ์ฝœ์„ ์ƒ์†๋ฐ›๋„๋ก ํ•˜๋Š” ๊ฒƒ. (ํ”„๋กœํ† ์ฝœ ์ƒ์†์€ ํ”„๋กœํ† ์ฝœ ์„ ์–ธํ•˜๋Š” ๊ณณ์—์„œ๋งŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Protocol๋„ static, class ํ”„๋กœํผํ‹ฐ, ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.


protocol KimFamily {
	static var lastName : String = "๊น€"
	class func lastNameInitial(): String 
}

Mutating Function


  • mutating function์€ protocol์—์„œ๋„ mutating์œผ๋กœ ํ‘œ์‹œํ•ด์•ผ ํ•œ๋‹ค.
  • mutating์œผ๋กœ ์„ ์–ธ๋œ ํ•จ์ˆ˜๋„ class์—์„œ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” mutating์„ ๋ถ™์ด์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
/**
 mutating์œผ๋กœ ์„ ์–ธ๋œ ํ•จ์ˆ˜๋„ class์—์„œ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” mutating์„ ๋ถ™์ด์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
 */

protocol Mutating {
    mutating func plus()
}

class MutatingClass: Mutating {
    var number: Int = 0
    
    func plus() {
        number += 1
    }
}

ํ”„๋กœํ† ์ฝœ์—์„œ initalizer๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.


ํด๋ž˜์Šค์—์„œ ํ”„๋กœํ† ์ฝœ์˜ initializer๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ, required ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์•ผ ํ•œ๋‹ค.

  • ์ด์œ : ๋ถ€๋ชจ ํด๋ž˜์Šค๊ฐ€ ๋”ฐ๋ฅด๋Š” ํ”„๋กœํ† ์ฝœ์„ ์ž์‹ ํด๋ž˜์Šค์—์„œ๋„ ๋”ฐ๋ผ์•ผ ํ•œ๋‹ค. ์ž์‹ ํด๋ž˜์Šค์—์„œ๋„ ํ”„๋กœํ† ์ฝœ์˜ initalizer๋ฅผ ๊ผญ ๊ฐ–๋„๋ก ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ.
protocol DefaultInitalizable {
    init()
}

class DefaultInitializer: DefaultInitalizable {
    required init() {}
}

final๋กœ ์„ ์–ธ๋œ ํด๋ž˜์Šค๋ผ๋ฉด, required๋ฅผ ๋ถ™์ด์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

final class FinalClas: DefaultInitalizable {
    init() {}
}

์ž์‹ ํด๋ž˜์Šค์—์„œ intialzier๋ฅผ ๊ฐ–๋Š” ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅผ๋•Œ, ์ด๋ฏธ ๋ถ€๋ชจ ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ํ”„๋กœํ† ์ฝœ์˜ initailizer์™€ ๋™์ผํ•œ ๊ฒƒ์„ ์ƒ์†๋ฐ›๋Š” ๋‹ค๋ฉด required override ๋ฅผ ๋ถ™์—ฌ์•ผ ํ•œ๋‹ค.

class SubClass: SuperClass, DefaultInitalizable {
    required override init() {}
}

ํ”„๋กœํ† ์ฝœ์—์„œ failable initializer๋„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

  • failable initialzer ๊ตฌํ˜„ ๋ฐฉ์‹
in ํ”„๋กœํ† ์ฝœ failable initializer nonfailable intializer
๊ตฌํ˜„์ฒด faliable initialzer nonfailable initializer
nonfailable initizlier implicitly unwrapped failable initializer
protocol FailableIntializable {
    init?()
}

class FailableIntialzier: FailableIntializable {
    required init() {}
}
protocol DefaultInitalizable {
    init()
}

class NonfailableInitializer: DefaultInitalizable {
    required init!() {}
}
๐Ÿ’ก implicitly unwrapped failable initialzier๋Š” ์–ธ์ œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ผ๊นŒ?
  1. init()?๋ฅผ nil์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š” intializer๋กœ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•  ๋•Œ
  2. init()? โ†’ init!()๋กœ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํ•  ๋•Œ

ํ”„๋กœํ† ์ฝœ์„ ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


  • ํ”„๋กœํ† ์ฝœ์„ ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•  ๋•Œ, ๊ตฌ์ฒด ํƒ€์ž…์—๋งŒ ์ •์˜๋˜์–ด์žˆ๋Š” ๊ฒƒ๋“ค์€ ์‚ฌ์šฉ ๋ชปํ•œ๋‹ค. ์˜ค์ง ํ”„๋กœํ† ์ฝœ์— ๋ช…์‹œ๋œ ๊ฒƒ๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๊ตฌ์ฒดํƒ€์ž…์—๋งŒ ์ •์˜๋˜์–ด์žˆ๋Š” ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์œผ๋ฉด downcasting์„ ํ•ด์•ผ ํ•œ๋‹ค.

Delegation ํŒจํ„ด


  1. ๊ฐ์ฒด์˜ ์ฑ…์ž„์„ ๋‹ค๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ๋Œ€์‹ ํ•ด๋‹ฌ๋ผ๊ณ  ๋งก๊ธฐ๋Š” ๊ฒƒ
  2. Delegation ํŒจํ„ด ๊ตฌํ˜„๋ฐฉ๋ฒ•: ๋‹ค๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ๋งž๊ธธ ์ฑ…์ž„์„ protocol๋กœ ๊ตฌํ˜„ํ•œ๋‹ค
  3. ์‚ฌ์šฉ์˜ˆ์‹œ
    1. ํŠน์ • ์•ก์…˜์— ์‘๋‹ตํ•˜๋Š” ๋กœ์ง์ด ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๊ฒŒ ํ•  ๋•Œ
      • button listener๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒโ†’ button์ด ๋ˆŒ๋ ธ์„ ๋•Œ์˜ ๋กœ์ง์„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ •์˜ํ•˜๊ฒŒ ํ•œ๋‹ค.
      • = ํ•œ ๊ฐ์ฒด์˜ ์ƒํƒœ ๋ณ€ํ™”๊ฐ€ ์ผ์–ด๋‚  ๋•Œ, ์ผ์–ด๋‚˜์•ผ ํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ delegate ํŒจํ„ด์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค.
    2. ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป์–ด์˜ฌ ๋•Œ, ๋ฐ์ดํ„ฐ์˜ ์ถœ์ฒ˜๋ฅผ ๋ชฐ๋ผ๋„ ๋ ๋•Œ
  4. ์‚ฌ์šฉ ์ด์œ 
    1. ๋ณด์ผ๋Ÿฌ ํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ๋ฅผ ์ค„์—ฌ์ค€๋‹ค.
    2. ๋™์ผํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ๋‹ค๋ฅด๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.
protocol Dice

์กฐ๊ฑด์— ๋”ฐ๋ผ์„œ Protocol์„ ๋”ฐ๋ฅด๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.


  • where๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ์ œ๋„ค๋ฆญ ์œ„์น˜์— ์–ด๋–ค ๊ตฌ์ฒด ํƒ€์ž…์ด ๋“ค์–ด์˜ค๋Š๋ƒ์— ๋”ฐ๋ผ์„œ, ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅผ์ง€ ๋ง์ง€๊ฐ€ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค.
protocol TextRepresentable {
	var description: String { get }
} 

extension Array: TextRepresentable where Element: TextRepresentable {
	var description: String {
		let itemAsText = self.map { $0.description }
		return "["+ itemsAsText.joined(seperator: ",") + "]"
	}
}

extension Dice: TextRepresentable {
	var description: String {
		return "A \(sides)-sided dice"
	}
}

let d6 = Dice()
let d12 = Dice()
let myDice = [d6, d12]
myDice.description // ๐Ÿ”ต

let lastNames = ["kim", "park"]
lastNames.description // โŒ ์ปดํŒŒ์ผ ์—๋Ÿฌ ๋ฐœ์ƒ
  • ์˜ˆ์‹œ ์„ค๋ช…: Array์˜ ์š”์†Œ(Element)๊ฐ€ TextRepresentable ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅผ ๋•Œ, Array๋„ TextRepresenteable์„ ๋”ฐ๋ฅธ๋‹ค.

  • ๋งŒ์ผ ํ”„๋กœํ† ์ฝœ ๊ตฌํ˜„์ฒด๊ฐ€ ์—ฌ๋Ÿฌ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•œ๋‹ค๋ฉด? Swift ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๊ฐ€์žฅ ๊ตฌ์ฒด์ ์ธ ์กฐ๊ฑด์„ ๊ฐ€์ง„ extension์„ ์‚ฌ์šฉํ•œ๋‹ค.

    extension Array: TextRepresentable where Element: TextRepresentable {
    	var description: String {
    		let itemAsText = self.map { $0.description }
    		return "["+ itemsAsText.joined(seperator: ",") + "]"
    	}
    }
    
    extension Array: TextRepresentable where Element: Int {
    	var description: String {
    		let itemAsTest = self.map { $0.description {
    		return "number:" + itemAsText.joined(seperator: ",")
    	}
    }
    
    let numbers = [1, 2, 3, 4, 5]
    print(numbers.description) // -> 2๋ฒˆ์งธ extension์˜ description์„ ์‚ฌ์šฉํ•œ๋‹ค.

์ด๋ฏธ ํ”„๋กœํ† ์ฝœ์˜ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์„ extension์œผ๋กœ ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋„๋ก ํ•  ๋•Œ


  • extension์˜ ๋ฐ”๋””๋ฅผ ๋น„์›Œ๋‘์–ด๋„ ๋œ๋‹ค.
protocol TextRepresentable {
	var description: String { get }
} 

struct Hamster {
	var name: String
	var description: String {
		return "A hamster named \(name)"
	}	
}

extension Hamster: TextRepresentable {}

Swift์—์„œ ์ œ๊ณตํ•˜๋Š” Equatable, Hashable, Comparable ํ”„๋กœํ† ์ฝœ์€ ํŠน์ • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋ฉด ํ”„๋กœํ† ์ฝœ ๊ตฌํ˜„์„ ์ž๋™์œผ๋กœ ํ•ด์ค€๋‹ค.


  1. Equatable ๊ตฌํ˜„์„ ์ž๋™์œผ๋กœ ํ•ด์ฃผ๋Š” ์กฐ๊ฑด
    1. Strcuture์˜ ๊ฒฝ์šฐ: ๋ชจ๋“  stored property๊ฐ€ Equatable์„ ๋”ฐ๋ฅผ ๋•Œ
    2. Enumeration์˜ ๊ฒฝ์šฐ: asssicatedtype์„ ๊ฐ€์ง€์ง€ ์•Š์„ ๋•Œ or ๋ชจ๋“  associatedtype์ด Equatable์„ ๋”ฐ๋ฅผ๋•Œ
  2. Hashable ๊ตฌํ˜„์„ ์ž๋™์œผ๋กœ ํ•ด์ฃผ๋Š” ์กฐ๊ฑด
    1. Strcuture์˜ ๊ฒฝ์šฐ: ๋ชจ๋“  stored property๊ฐ€ Hashable์„ ๋”ฐ๋ฅผ ๋•Œ
    2. Enumeration์˜ ๊ฒฝ์šฐ: asssicatedtype์„ ๊ฐ€์ง€์ง€ ์•Š์„ ๋•Œ or ๋ชจ๋“  associatedtype์ด Hashable์„ ๋”ฐ๋ฅผ๋•Œ
  3. Comparable ๊ตฌํ˜„์„ ์ž๋™์œผ๋กœ ํ•ด์ฃผ๋Š” ์กฐ๊ฑด
    1. Enumerataion์˜ ๊ฒฝ์šฐ: rawValue๋ฅผ ๊ฐ–์ง€ ์•Š์„๋•Œ or assciatedtype์„ ๊ฐ€์ง€๋ฉด ๋ชจ๋“  assocatedtype์ด Comparable์„ ๋”ฐ๋ฅผ ๋•Œ

ํ”„๋กœํ† ์ฝœ ํ•ฉ์„ฑ


  • ํ”„๋กœํ† ์ฝœ์„ ํ•ฉ์ณ์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ
  • ํ˜•ํƒœ: SomeProtocol & AnotherProtocol
  • ํ”„๋กœํ† ์ฝœ ํ•ฉ์„ฑ์— Class๋ฅผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹จ, 1๊ฐœ์˜ ํด๋ž˜์Šค๋งŒ ๊ฐ€๋Šฅ
  • ์˜ˆ์‹œ) Named ํ”„๋กœํ† ์ฝœ, Aged ํ”„๋กœํ† ์ฝœ ํ•ฉ์„ฑ
protocol Named {
    var name: String { get set }
}

protocol Aged {
    var age: Int { get set }
}

struct Person: Named & Aged {
    var name: String
    var age: Int
}

func wishHappyBirthday(to celebrator: Named & Aged) {
    print("Happy Birthday, \(celebrator.name), you're \(celebrator.age)")
}
  • wishHappyBirthday๋Š” Named์™€ Agedํ”„๋กœํ† ์ฝœ์„ ๋ชจ๋‘ ๊ตฌํ˜„ํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
  • ๊ตฌ์ฒดํƒ€์ž…์ด ๋ฌด์—‡์ธ์ง€๋Š” ์ƒ๊ด€์ด ์—†๋‹ค!
๐Ÿ’ก `struct Person: SomeProtocol, AnotherProtocol` ๊ณผ ์ฐจ์ด์ ์ด ๋ฌด์—‡์ธ๊ฐ€?
  • ๋งŒ์ผ SomeProtocol๊ณผ AnotherProtocol์„ ๊ตฌํ˜„ํ•œ ํƒ€์ž…์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.
func foo(person: Person)

func foo(abstract: SomeProtocol & AnotherProtocol)
  • ์ฒซ๋ฒˆ์งธ foo()๋Š” Person ์ธ์Šคํ„ด์Šค๋งŒ ์ธ์ž๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

  • ๋‘๋ฒˆ์งธ foo()๋Š” Person ์ธ์Šคํ„ด์Šค ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ SomeProtocol๊ณผ AnotherProtocol์„ ๊ตฌํ˜„ํ•œ ํƒ€์ž…์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

    โ†’ ๋‘๋ฒˆ์งธ foo()๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

ํŠน์ • ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋Š”์ง€ ์ฒดํฌ


  • is : true ๋ฐ˜ํ™˜ โ†’ ํŠน์ • ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ
  • as? :downcasting ์‹œ๋„ ์„ฑ๊ณตย โ†’ ํŠน์ • ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ
  • as! : downcasting ์‹œ๋„ ์„ฑ๊ณต, ์‹คํŒจ์‹œ runtime errorย โ†’ ํŠน์ • ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ

Optional Requirement


  • ํ”„๋กœํ† ์ฝœ์˜ ๊ตฌ์„ฑ์š”์†Œ ์ค‘ ๊ตฌํ˜„ํ•ด๋„ ๋˜๊ณ , ์•ˆํ•ด๋„ ๋˜๋Š” ๊ฒƒ์„ Optional Requirement๋ผ๊ณ  ํ•œ๋‹ค.

  • ์‚ฌ์šฉ ๋ฐฉ๋ฒ•:

    @objc protocol CounterDataSource {
    	@objc optional func increment(forCount count: Int) -> Int
    	@objc optional var fixedIncrement: Int { get }
    }
    • ์„ ์–ธํ•  ๋•Œ: optional ํ‚ค์›Œ๋“œ ์‚ฌ์šฉ & @objc ํ‚ค์›Œ๋“œ ์‚ฌ์šฉ

      @objc ํ”„๋กœํ† ์ฝœ์€ ํด๋ž˜์Šค or @objc ํด๋ž˜์Šค๋งŒ ๋”ฐ๋ฅผ ์ˆ˜ ์žˆ๋‹ค.

    • ์‚ฌ์šฉํ•  ๋•Œ:

      • ๋ฉ”์„œ๋“œ์˜ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•  ๋•Œ ? ํ‘œ์‹œ
      • ํ”„๋กœํผํ‹ฐ์˜ ๊ฒฝ์šฐ optional ํƒ€์ž…์ด ๋œ๋‹ค.
      • (๊ตฌํ˜„๋˜์–ด์žˆ์ง€ ์•Š์•˜์„ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.)
  • ์–ธ์ œ ์‚ฌ์šฉ? Objective-Cํ•˜๊ณ  ๊ฐ™์ด ๋™์ž‘ํ•ด์•ผ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ๋•Œ

์‚ฌ์šฉ ์˜ˆ์‹œ


  • ์• ํ”Œ์—์„œ ๊ถŒ์žฅ: ๋‹ค์ค‘ ์ƒ์†์„ ํ†ตํ•ด โ†’ ๊ธฐ๋Šฅ์„ ์กฐ๋ฆฝํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ
  • ์ถ”์ƒํ™” ์ˆ˜๋‹จ (๊ฐ์ฒด์ง€ํ–ฅ์—์„œ ์ธํ„ฐํŽ˜์ด์Šค(์ž๋ฐ”์˜ ๊ทธ ์ธํ„ฐํŽ˜์ด์Šค ์•„๋‹˜) ๊ตฌํ˜„ํ•  ๋•Œ ์‚ฌ์šฉ)
  • DIP๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ์‚ฌ์šฉ
  • Delegate ํŒจํ„ด