티스토리 뷰

Delegate Pattern은

iOS에서 많이 사용되는 디자인 패턴이에요.

 

객체 프로그래밍에 있어 하나의 객체가 모든 일을 처리하는게 아니라

처리하는 부분만 똑 떼어내어 따로 객체로 만들어주고 그걸 넘기는(위임: Deletate) 방법입니다.

 

abc.delegate = self 많이 봐왔습니다.

self(viewController)에서 abc의 기능들을 쓰겠다는 뜻.

 

구체적인 예시를 보겠습니다.

 

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.delegate = self
        tableView.dataSource = self
    }
}

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        return cell
    }
}

 

예시로 기본적인 TableView의 사용입니다.

 

UITableViewDelegate와, UITableViewDataSource를 extension해주었죠? ( 프로토콜을 채택했다는 뜻 )

 

 

추가설명 ( 각각의 프로토콜의 내부 기능 )

 

UITableViewDelegate에는 테이블 뷰의 셀을 편집하거나

이벤트(ex.didSelectRowAt) 처리 등의 메소드가 선언 되어 있음.

 

UITableViewDataSource에는 필수로 선언되어야하는

셀 개수와 셀 설정 함수가 있죠. ( 필수 외에도 optional 메소드가 많이 있음.. )

 

>> 이런 함수들을 위임하여 사용하는게 delegate pattern 목적

 

 

아무튼 프로토콜을 채택 후

 

tableView.deleagte = self 

tableView.dataSource = self

 

이렇게 위임자가 누구인지 알려주면 ( *위임자 : 동작을 대신해줄 사람 )

UITableViewDelegate, UITableViewDataSource에 정의된 여러 메소드들을 self(==VC)에서 사용하겠단 뜻

 

이게 delegate 패턴 방식에서 위임을 하기 위한 방식입니다.

 

여기서!! 위임자를 알려주는 코드에서 delegatedataSource가 뭐냐하면 protocol 변수 입니다.

 

 

UIKit.UITableView 내부

 

변수로 선언된 dataSource의 주인공인 UITableViewDataSource로 들어가 보면

 

UITableViewDataSource

 

UITableViewDataSource는 protocol 타입인 모습.

그리고 그 protocol 안에는 여러 함수가 선언되어 있음.

 

고로 delegate pattern 의 사용 방법을 정리 하자면 !!

 

1. 특정 기능을 할 함수를 protocol 안에 깡통함수로 선언해줍니다. 

 

2. 그리고 그 protocol을 변수로 선언. ( ex. 프로토콜 tableVIewDataSource와 프로토콜 변수 dataSource )

 

3. 그러고 이제 vc에서 프로토콜을 채택해주고 ( extension )

 

4. 그 프로토콜 변수에 self(해당 vc)로 대리자를 위임.

tableView.dataSource = self ( 이제 tableView의 dataSource관련 일은 내가 대신할게 )

 

5. self인 뷰컨트롤러에서 dataSource 관련 업무들을 수행하도록 구현해주면

 

이게 바로 업무에 대한 부분을 객체로 만들어주고 그걸 넘기는(위임: Deletate) 디자인 패턴.

 

 

 

 

 

 

 

여기서부턴 활용편입니다.

 

 

 

 

 

 

delegate로 데이터 넘기기 !

 

delegate가 func만 위임하는게 아니라 (vc간에) 데이터도 넘길 수 있어요!

 

보통 vc(viewController)를 push 하면서 데이터를 넘길때는 segue로 데이터를 넘기는데. 

반대로 pop 될 때는 vc가 dismiss되면서 데이터가 유실되기 때문에 segue로 데이터 넘겨줄 수 가 없어요.

 

이걸 이제 delegate로 해결 가능합니다.

notification으로도 가능한데 보통 notification은 수신받는 객체가 많을 때.

delegate는 하나의 객체가 여러가지 요구를 받을때 사용됩니다.

 

delegate로 데이터 주고 받는 방법에 대해 추가 작성하겠습니다.

 

이건 제 메모앱 프로젝트의 delegate로 데이터 전달받는 예제입니다.

(detailVC는 첫번째, createVC는 두번째vc입니다.)

 

두번째VC에서

메모를 쓰고 save를 누르면 해당 vc가 dimiss되면서 메모의 데이터를 전달하도록 합니다.

 

 

메모를 create하는 vc에서 (메모)데이터를 전달하는 함수를 포함하는 protocol을 생성해줍니다. ( SendDateDelegate )

 

protocol의 함수는 깡통이라그랬었죠?

 

깡통함수를 가진 프로토콜을 이제 채택(extension)하고 위임(.delegate = self)한 곳에서

"이 함수를 이렇게 쓸거다" 하고 깡통함수를 구현해주면 완성입니다.

 

아무튼 protocol 을 생성 해주었고 class 안에 그 protocol 변수를 만들어줍니다. ( var delegate )

 

그 다음.

 

 

메모를 save 하고자 할 때, 전달하고자 하는 data를 delgate.sendDate의 인자로 넣어주고. dismiss 하는 모습.

 

 

 

그러고 이제 dimiss 된 vc(첫번째VC)에서 protocol을 채택합니다.

 

채택하고 채택한 프로토콜의 함수를 구현해주는 모습. ( memo 라는 변수에 전달되어온 data를 저장합니다 )

 

 

그러고 prepare 할때 vc.delegate= self( self 는 현재 vc == 첫번째 vc )로 위임하며

 

"SendDateDelegate의 sendData 함수는 내가 처리할게" 라고 해줍니다 ( memo = data 라고 구현해줌 )

 

이렇게 데이터 전달이 가능합니다.

 

delegate pattern을 활용하여 dimiss될 때 데이터를 전달하는 방법을 정리했습니다.

 

 

메모앱 프로젝트도 올려둘게요.

 

주소는 https://github.com/JangJaeHyung1/JangMeMo 입니다.

(꿀팁. github1s.com/Jang~ 이렇게 1s를 넣어주면 코드로 바로 볼수있다는거 아시나요?)

 

프로젝트에서 delegate를 보실분은

DetailViewController와 CreateMemoViewController를 살펴봐주세요.

 

 

 

감사합니다!

 

 

 

댓글