<commit_before>---
layout: post
title: "Delegate Pattern"
author: "younari"
---

# Delegate Pattern
### Sources from
- [Swift4 - Protocols](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html)

# Protocol
- 프로토콜은 method, property 등으로 요구 사항의 청사진을 정의한다.
- 클래스, 구조체, 열거형이 프로토콜을 채택했을 때, 프로토콜에서 요구한 사항에 대해 구현해야 한다.
- 프로토콜을 통해 공통적인 **작업을 강제** 할수 있다.
- 실제 구현은 class, Struct, Enum에서 한다.
- 프로토콜을 타입처럼 사용 가능하다.

## Example

{% highlight swift %}
protocol Runable {
	var regCount:Int {get set} // regCount 프로퍼티를 무조건 만들어야 하며, getter, setter를 모두 구현해야 한다.
 	func run()
}
{% endhighlight %}


# Delegate
- 클래스나 구조체에서 할 일의 일부를 다른 인스턴스에게 대신 하게 하는 디자인 패턴


# UITableViewDelegate 프로토콜 선언

{% highlight swift %}
public protocol UITableViewDelegate : NSObjectProtocol, UIScrollViewDelegate {

    // Display customization
    
    @available(iOS 2.0, *)
    optional public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)

    @available(iOS 6.0, *)
    optional public func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int)

    @available(iOS 6.0, *)
    optional public func tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int)

    @available(iOS 6.0, *)
    optional public func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath)

...

{% endhighlight %}

# UITableView클래스에 delegate 프로퍼티 생성
- UITableView는 View 스스로가 결정할 수 없는 부분을 ViewController에게 위임하고자 한다. (ex. cellForRowAt)
- 따라서 UITableViewDelegate 프로토콜을 채택한 인스턴스를 저장할 delegate 프로퍼티를 갖고 있다.

{% highlight swift %}
open class UITableView : UIScrollView, NSCoding, UIDataSourceTranslating {

    
    public init(frame: CGRect, style: UITableViewStyle) // must specify style at creation. -initWithFrame: calls this with UITableViewStylePlain

    public init?(coder aDecoder: NSCoder)

    
    open var style: UITableViewStyle { get }

    
    weak open var dataSource: UITableViewDataSource?

    weak open var delegate: UITableViewDelegate?
    
    
    ...
    
{% endhighlight %}


# 구현부
- ViewController에서 UITableViewDelegate 프로토콜을 채택 → 
- ViewController는 UITableViewDelegate 프로토콜이 강제하는 메소드를 모두 정의 → 
- UITableView 의 인스턴스인 tableView 생성 → 
- tableView의 delegate에 자신(ViewController)을 대입

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UIScrollViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        let tableView: UITableView = UITableView(frame: view.bounds, style: .plain)
        tableView.dataSource = self // UITableViewDataSource 선언
        tableView.delegate = self // UITableViewDelegate 선언
        
        // class 로서 tableView에 등록
        tableView.register(Cell.self, forCellReuseIdentifier: "Cell")
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "UITableViewCell")
        // UITableViewCell.self : class이름.self = 클래스 자체
        // dequeueReusableCell 얘가 UI를 만들 수 있도록 등록하는 과정
        view.addSubview(tableView)
    }<commit_msg>delegate<commit_after>---
layout: post
title: "Delegate Pattern"
author: "younari"
---

# Delegate Pattern
### Sources from
- [Swift4 - Protocols](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html)

# Protocol
- 프로토콜은 method, property 등으로 요구 사항의 청사진을 정의한다.
- 클래스, 구조체, 열거형이 프로토콜을 채택했을 때, 프로토콜에서 요구한 사항에 대해 구현해야 한다.
- 프로토콜을 통해 공통적인 **작업을 강제** 할수 있다.
- 실제 구현은 class, Struct, Enum에서 한다.
- 프로토콜을 타입처럼 사용 가능하다.

## Example

{% highlight swift %}
protocol Runable {
	var regCount:Int {get set} // regCount 프로퍼티를 무조건 만들어야 하며, getter, setter를 모두 구현해야 한다.
 	func run()
}
{% endhighlight %}


# Delegate
- 클래스나 구조체에서 할 일의 일부를 다른 인스턴스에게 대신 하게 하는 디자인 패턴


# UITableViewDelegate 프로토콜 선언

{% highlight swift %}
public protocol UITableViewDelegate : NSObjectProtocol, UIScrollViewDelegate {

    // Display customization
    
    @available(iOS 2.0, *)
    optional public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)

    @available(iOS 6.0, *)
    optional public func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int)

    @available(iOS 6.0, *)
    optional public func tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int)

    @available(iOS 6.0, *)
    optional public func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath)

...

{% endhighlight %}

# UITableView클래스에 delegate 프로퍼티 생성
- UITableView는 View 스스로가 결정할 수 없는 부분을 ViewController에게 위임하고자 한다. (ex. cellForRowAt)
- 따라서 UITableViewDelegate 프로토콜을 채택한 인스턴스를 저장할 delegate 프로퍼티를 갖고 있다.

{% highlight swift %}
open class UITableView : UIScrollView, NSCoding, UIDataSourceTranslating {

    
    public init(frame: CGRect, style: UITableViewStyle) // must specify style at creation. -initWithFrame: calls this with UITableViewStylePlain

    public init?(coder aDecoder: NSCoder)

    
    open var style: UITableViewStyle { get }

    
    weak open var dataSource: UITableViewDataSource?

    weak open var delegate: UITableViewDelegate?
    
    
    ...
    
{% endhighlight %}


# 구현부
- ViewController에서 UITableViewDelegate 프로토콜을 채택 → 
- ViewController는 UITableViewDelegate 프로토콜이 강제하는 메소드를 모두 정의 → 
- UITableView 의 인스턴스인 tableView 생성 → 
- tableView의 delegate에 자신(ViewController)을 대입

{% highlight swift %}

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UIScrollViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        let tableView: UITableView = UITableView(frame: view.bounds, style: .plain)
        tableView.dataSource = self // UITableViewDataSource 선언
        tableView.delegate = self // UITableViewDelegate 선언
        
        // class 로서 tableView에 등록
        tableView.register(Cell.self, forCellReuseIdentifier: "Cell")
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "UITableViewCell")
        // UITableViewCell.self : class이름.self = 클래스 자체
        // dequeueReusableCell 얘가 UI를 만들 수 있도록 등록하는 과정
        view.addSubview(tableView)
    }
    
{% endhighlight %}
{'fraction_non_alphanumeric': 0.08496525584333543, 'fraction_numerical': 0.002842703727100442, 'mean_word_length': 3.7050520059435366, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2202813', 'n_tokens_mistral': 2599, 'n_tokens_neox': 2822, 'n_words': 597}