[TIL] 21.04.12.(Mon)

Ryan (Geonhee) Son·2021년 5월 1일
0
post-thumbnail

활동 요약

  • 활동학습
    • 고차함수와 클로저
  • Class Diagram Update
  • 텍스트 UI 요소 3가지
  • STEP 2 PR
    • 실행 화면
    • final 키워드의 적용
    • Style - extension을 활용한 protocol conformance의 분리

활동 상세

고차함수와 클로저

미리 관심가는 분야를 공부해두었더니 활동 학습에서 복습하며 돌이켜볼 수 있었습니다.
학습 내용은 이전에 정리해둔 내용과 동일한 내용입니다.
[Swift] 고차함수와 클로저 축약 표현

Class Diagram Update

진행 중인 프로젝트의 클래스 다이어그램을 업데이트 하였다. 다이어그램 작성은 draw.io를 이용하고 있다.

[iOS] 텍스트 관련 UI 요소 세 가지 비교

프로젝트를 수행하며 텍스트 요소를 다루는 UI 요소 중 무엇을 선택하여 사용하여야 할지 고민하게 될 때가 있습니다. 어떤 상황에서 사용하여야 할지 결정하기 위해 간단하게 차이점을 정리해보겠습니다.

UILabel

읽기 전용인 Static Text String을 보여줄 때 사용합니다.

  • 선택이 불가능하므로 사용자가 텍스트를 선택하여 복사하거나 공유할 수 없습니다.

UITextField

편집 가능한 한 줄 텍스트 공간을 사용자에게 제공할 때 사용합니다.

  • 언급하였듯 여러 줄 입력을 지원하지 않습니다.

UITextView

편집 가능한 여러 줄 텍스트 공간을 사용자에게 제공할 때 사용합니다.

  • UIScrollView를 상속하고 있어 기본적으로 스크롤 기능을 제공합니다.
  • 스크롤, 편집, 데이터 디텍터 (Phone Number, Link, Address, Calender Event 등의 내용을 자동으로 인식) 기능을 제공하며 해당 기능들을 자유롭게 활성화 또는 비활성화 할 수 있습니다.
  • isSelectable 프로퍼티를 제공하여 사용자가 텍스트를 선택하게끔 지원할 수 있고, 이를 통해 복사, 공유 등의 작업을 할 수 있도록 도와줍니다. 물론 비활성화하여 UILabel처럼 텍스트를 선택하지 못하게 설정할 수 있습니다.

아래 이미지는 UITextView가 제공하는 기능의 일부입니다.

지금까지 iOS에서 활용할 수 있는 세 가지 텍스트 관련 UI 요소를 알아보았습니다.

참고자료

만국박람회 Step 2 PR

두 번째 Step을 수행하고 코드 리뷰를 받기 위해 PR을 보냈습니다.

Step 2 수행 간 고민한 점

  1. 메인화면: Scroll ViewContent Layout Guide를 활용하여 스크롤 뷰를 구현하는 방법
  • 관련하여 작성한 포스트
  • Scroll View 안에 포함된 Text ViewIntrinsic size를 가지게 하는 방법 -> Text ViewScrolling Enabled 속성 비활성화
  1. Navigation Controller 적용 방법
  • 관련하여 작성한 포스트
  • 스토리보드에서 적용하고 싶은 View Controller를 선택하고 Xcode 상단의 Editor -> Embed In -> Navigation Controller 선택
  1. Table View에서 다음 뷰 컨트롤러에 데이터를 전달하는 방법

실행 화면

만국박람회 프로젝트 Step 2는 세로 화면에 대응하는 화면과 기능을 개발하는 것이었습니다.

final 키워드의 적용

타 프로그래밍 언어에서와 마찬가지로 Swift 또한 클래스의 상속을 지원합니다. 더 이상 해당 클래스에서 하위 클래스로의 전체 클래스 또는 일부 (메서드, 프로퍼티)가 상속 또는 상속에 따른 재정의가 될 필요가 없다고 판단한 경우 final 키워드를 각 요소 앞에 추가함으로써 상속을 방지할 수 있죠. The Swift Programming Language (Swift 5.4) - Inheritance에서는 아래와 같이 설명하고 있습니다.

Source: The Swift Programming Language (Swift 5.4) - Inheritance

final 키워드 적용이 성능에 미치는 영향

그럼 final 키워드 적용을 하면 성능에는 어떤 영향을 미칠까요? 비록 공식 문서에서는 성능과 관련된 사항을 언급하고 있지 않지만, 이 문서에서는 final로 선언된 요소들은 직접 호출하는 반면, 그렇지 않은 요소들은 vtable을 통해 간접 호출되어 직접 호출되는 경우보다 느리게 작동한다고 소개하고 있습니다.

vtable?

vtable은 가상 메서드 테이블을 이르는 것으로, virtual method table, virtual function table, virtual call table, dispatch table, vftable 등으로 부르기도 합니다. 메서드 오버라이딩에 따라 실행 시점에 어떤 메서드를 실행할지 결정하는 동적 디스패치를 지원하기 위해 프로그래밍 언어에서 사용하는 메커니즘이죠.

상기 언급한 바와 같이 오버라이딩한 메서드는 실행 시점에 어떤 메서드를 실행할지 결정하는 반면, final 키워드가 적용된 메서드는 컴파일 시점에 어떤 메서드를 실행할지 결정할 수 있으므로 성능 상 이점을 가진다고 할 수 있습니다.

참고자료

Protocol 채택 시 extension을 활용하여 가독성을 높이는 방법

Source: Raywenderlich Swift Style Guide

Swift의 protocol을 활용하면 class를 상속하여 사용하는 것에 비해 다른 타입에 대한 의존도를 상당히 낮출 수 있습니다. 서로 다른 타입에서 동일한 프로토콜을 적용하여도 최소한의 요구사항만 만족시키면 되기에 채택하는 타입에서 자유롭게 구현 방식을 달리해도 되죠. 복수의 protocol를 채택하는 경우 타입 내 프로퍼티와 메서드가 많아져 가독성이 떨어질 수 있는데요, 이런 경우에는 extension을 활용하여 해당 protocol이 요구한 사항들을 extension에 분리하여 작성해주면 가독성을 높일 수 있습니다.

아래는 UIViewController를 활용하여 TableView를 구현한 사례를 나타낸 것입니다. 아시다시피 TableView를 구현하기 위해 UITableViewDelegateUITableViewDataSource 프로토콜을 채택하여 요구하는 메서드들을 구현해야하죠. 아래 코드 또한 첫 final classUIViewController를 상속 받아 사용하는 내용만, 따라오는 두 개의 extension에서는 각각 UITableViewDataSourceUITableViewDelegate 내용을 구현하고 있습니다.

import UIKit
import OSLog

final class ArtworksTableViewController: UIViewController {
  (... 불필요 부분 생략 ...)
}

// MARK: - Table view data source
extension ArtworksTableViewController: UITableViewDataSource {
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return artworks.count
  }
  
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: ArtworkTableViewCell = tableView.dequeueReusableCell(
      withIdentifier: Identifier.Cell.artwork,
      for: indexPath
    ) as! ArtworkTableViewCell
    
    cell.thumbnailImageView.image = UIImage(named: artworks[indexPath.row].imageName)
    cell.titleLabel.text = artworks[indexPath.row].name
    cell.shortDescriptionLabel.text = artworks[indexPath.row].shortDescription
    
    return cell
  }
}

// MARK: - Table view delegate
extension ArtworksTableViewController: UITableViewDelegate {
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: false)
  }
}

해당 내용은 Raywenderlich Swift Style Guide에서도 권장하고 있는 사항이니 잘 지켜주면 좋을 것 같네요.

참고자료

profile
합리적인 해법 찾기를 좋아합니다.

0개의 댓글