본문 바로가기

iOS (스파르타)

indexPath, 데이터소스와 델리게이트, 프로토콜선언

indexPath 에 대한 설명

indexPath는 테이블 뷰의 특정 셀 위치를 나타내는 객체이다. 테이블 뷰는 여러 섹션으로 나뉠 수 있으며, 각 섹션에는 여러개의 행(row)이 있을 수 있다.

  • indexPath.section: 섹션 번호를 나타낸다. 예를 들어, 테이블 뷰가 여러 섹션으로 나누어져 있다면, 0부터 시작하는 섹션 인덱스를 사용한다.
  • indexPath.row: 특정 섹션 내의 행 번호를 나타낸다. 이 값도 0부터 시작한다.

따라서 indexPath 는 테이블 뷰의 셀을 정확히 식별하기 위한 섹션과 행 정보를 포함한다. 이를 통해 테이블 뷰 데이터 소스는 각 셀에 대한 데이터를 적절히 설정할 수 있다.

 


 

 

데이터소스와 델리게이트

데이터소스(DataSource): 데이터소스는 테이블 뷰나 컬렉션 뷰에 표시될 데이터를 제공하는 역할을 한다. 예를 들어, 테이블 뷰에 몇개의 섹션과 몇개의 행이 있는지, 각 셀에 어떤 데이터가 표시될지 등을 결정한다. 데이터소스는 UITableViewDataSource 프로토콜을 준수해야 한다.

 

델리게이트(Delegate): 델리게이트는 테이블 뷰나 컬렉션 뷰의 동작과 관련된 결정을 처리한다. 예를들어, 특정 셀이 선택되었을 때의 반응이나 셀의 높이를 설정하는 것과 같은 행동을 관리한다. 델리게이트는 UITableViewDelegate 프로토콜을 준수해야한다.

 

클래스 내부 선언과 extension으로의 분리

두가지 방법 모두 가능하며, 주로 코드 구조와 가독성의 문제이다.

1. 클래스 내부에서 선언

데이터소스와 델리게이트 메서드를 클래스 내부에서 직접 선언하는 방법이다. 예를들어,

class MyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    // ViewController의 모든 코드, 프로퍼티, 메서드 등이 포함

    // UITableViewDataSource 메서드
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return orders.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // 셀 구성 코드
    }

    // UITableViewDelegate 메서드
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // 셀이 선택되었을 때의 동작
    }
}

장점:

  • 모든 관련 코드가 한곳에 모여있어 찾기가 쉽다.
  • 작은 규모의 프로젝트에서는 관리가 쉬울 수 있다.

단점:

  • 클래스가 복잡해질 경우 코드가 길어지고 가독성이 떨어질 수 있다..
  • 뷰 컨트롤러가 여러 프로토콜을 채택하는 경우 코드가 복잡해진다.

2. extension으로 분리

데이터 소스와 델리게이트를 extension으로 분리하는 방법. 예를 들어

class MyViewController: UIViewController {
    // ViewController의 다른 코드, 프로퍼티, 메서드 등이 포함
}

extension MyViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return orders.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // 셀 구성 코드
    }
}

extension MyViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // 셀이 선택되었을 때의 동작
    }
}

장점:

  • 각 기능을 분리된 extension으로 나누어 관리하기 때문에 코드가 깔끔하고 명확해짐.
  • 특정 기능과 관련된 코드 블록을 빠르게 찾을 수 있다.
  • 유지보수와 가독성이 높아진다.
  • 다수의 프로토콜을 준수할 때 코드가 혼란스러워지는 것을 방지할 수 있다.

단점:

  • 각 기능별로 파일이 나누어질 경우, 처음 보는 사람에게는 필요한 기능이 어디에 있는지 파악하기 어려울 수 있다.
  • 작은 규모의 프로젝트에서는 코드가 너무 많이 분리될 수 있다.

결론

데이터 소스와 델리게이트 메서드를 클래스 내부에 선언하든 extension으로 분리하든 개발자의 스타일과 프로젝트의 복잡성에 따라 다르다. 작은 프로젝트에서는 한 클래스에 모두 포함시키는 것이 간단하고 효율적일 수 있지만, 큰 프로젝트에서는 코드의 가독성과 유지보수성을 높이기 위해 extension으로 분리하는 것이 더 좋다. 특히, extension을 사용하면 클래스 본체와 프로토콜 구현부를 명확하게 구분할 수 있어 코드구조가 더 체계적이고 이해하기 쉬워진다.

 


 

 

프로토콜(Protocol)은 클래스(class), 구조체(struct), 열거형(enum) 등 타입의 정의에 상관없이 독립적으로 선언할 수 있는 기능입니다. Swift에서 프로토콜은 특정 기능을 수행하기 위한 메서드, 속성, 기타 요구사항의 청사진을 정의합니다. 클래스나 구조체, 열거형이 프로토콜을 채택(adopt)하게 되면, 해당 프로토콜이 요구하는 속성과 메서드를 반드시 구현해야 합니다.

 

프로토콜 선언 위치

프로토콜은 일반적으로 파일의 최상단에, 클래스나 구조체, 열거형 정의와 별도로 독립적으로 선언됩니다. 예를 들어, 하나의 Swift 파일에서 다음과 같이 선언할 수 있습니다:

protocol SomeProtocol {
    var someProperty: String { get }
    func someMethod()
}

class SomeClass: SomeProtocol {
    var someProperty: String = "Hello"
    func someMethod() {
        print("Method implemented")
    }
}

위 코드에서 SomeProtocol은 독립적으로 선언된 후, SomeClass가 이 프로토콜을 채택하여 요구된 프로퍼티와 메서드를 구현하고 있습니다.

 

프로토콜 선언과 클래스 선언의 위치 관계

  • 독립적인 선언: 프로토콜은 클래스, 구조체, 열거형과 별도로 선언됩니다. 이렇게 함으로써, 같은 프로토콜을 여러 클래스나 구조체 등이 채택할 수 있습니다. 또한, 파일의 최상단이나 다른 파일에 선언할 수 있어 코드의 재사용성과 모듈성을 높일 수 있습니다.
  • 타입의 선언 내에서의 사용: 클래스나 구조체, 열거형은 선언 시점에 프로토콜을 채택할 수 있습니다. 예를 들어, 위의 예제처럼 클래스 선언부에서 : SomeProtocol을 통해 프로토콜을 채택하고, 그에 대한 요구사항을 구현합니다.
  •  
class AnotherClass: SomeProtocol {
    var someProperty: String = "Another Hello"
    func someMethod() {
        print("Another method implementation")
    }
}

AnotherClass도 SomeProtocol을 채택하고 그 요구사항을 구현할 수 있습니다. 이는 프로토콜이 클래스 선언 전에나 후에 독립적으로 선언될 수 있다는 것을 의미합니다.

 

요약

 

프로토콜은 특정 타입(class, struct, enum)에 종속되지 않으며, 어디서든 독립적으로 선언할 수 있습니다. 클래스, 구조체, 열거형은 이 프로토콜을 채택할 수 있으며, 프로토콜이 요구하는 속성과 메서드를 구현해야 합니다. 따라서 "프로토콜은 클래스 위에서 선언해야 한다"는 잘못된 표현이며, 프로토콜은 해당 프로토콜을 채택하고 구현하는 타입의 위치와 상관없이 독립적으로 선언됩니다.

'iOS (스파르타)' 카테고리의 다른 글

깃허브 커밋 메세지  (0) 2024.08.09
무한스크롤~!  (0) 2024.08.08
Delegate 패턴 이해하기  (0) 2024.07.30
UserDefaults ,,,  (0) 2024.07.28
네비게이션컨트롤러 사용시 루트뷰로 돌아가기~  (0) 2024.07.26