팩토리 패턴으로 만든 UIComponent의 실제사용에서 메모리 최적화 고민

임혜정·2024년 9월 8일
0
post-custom-banner

프로젝트를 시작하며 조금이라도 개발 속도를 빠르게 해줄 수 있는 것이 무엇일까 생각해보았다. 반드시 반복될 수 밖에 없는 코드들, 레이블과 버튼같은 ui요소들을 정의를 빠르고 쉽게할 수 있지 않을까 했다.
그래서 찾아보고 구현한 것이 팩토리패턴으로 UIComponent를 정의해놓고 타이틀,컨텐츠본문같은 레이블을 팀원들이 빠르게 작성할 수 있게하여 view코드만이라도 빠르게 해보자라는 의도를 갖고 있었다.

내가 만든 UIComponent

// UIComponent 파일의 레이블 생성기 부분
protocol LabelFactory {
    func createLabel(with text: String, color: UIColor) -> UILabel
}

class BaseLabelFactory: LabelFactory {
    func createLabel(with text: String, color: UIColor) -> UILabel {
        let label = UILabel()
        label.textAlignment = .left
        label.text = text
        label.textColor = color
        return label
    }
}

class LargeTitleLabel: BaseLabelFactory {
    override func createLabel(with text: String, color: UIColor) -> UILabel {
        let label = super.createLabel(with: text, color: color)// 매개변수는 레이블 각각이 다 다를 부분
        label.font = UIFont.boldSystemFont(ofSize: 24) // 레이블의 성격따라 다를 부분
        return label
    }
}

class SmallTitleLabel: BaseLabelFactory {
    override func createLabel(with text: String, color: UIColor) -> UILabel {
        let label = super.createLabel(with: text, color: color)
        label.font = UIFont.boldSystemFont(ofSize: 20)
        return label
    }
}

class ContentLabel: BaseLabelFactory {
    override func createLabel(with text: String, color: UIColor) -> UILabel {
        let label = super.createLabel(with: text, color: color)
        label.font = .systemFont(ofSize: 16)
        return label
    }

레이블 요소만을 예로 들면,
반드시 반복되는 레이블요소를 base로 지정해두고 그 중에서 대제목,소제목,본문 레이블의 속성을 지정했다.
그리고 자주 변화할 수 밖에 없겠다하는 텍스트와 컬러부분을 매개변수로 받을 수 있게 함.

만약 UIComponent가 없이 작업한다면

    private let 대제목Label: UILabel = {
        let label = UILabel()
        label.text = "대제목"
        label.textAlignment = .left
        label.font = .systemFont(ofSize: 24)
        label.numberOfLines = 0
        label.textColor = UIColor.black
        return label
    }()
    
    private let 소제목Label: UILabel = {
        let label = UILabel()
        label.text = "소제목"
        label.textAlignment = .left
        label.font = .systemFont(ofSize: 20)
        label.numberOfLines = 0
        label.textColor = UIColor.black
        return label
    }()
    
    private let 본문Label: UILabel = {
        let label = UILabel()
        label.text = "본문"
        label.textAlignment = .left
        label.font = .systemFont(ofSize: 18)
        label.numberOfLines = 0
        label.textColor = UIColor.black
        return label
    }()
    

장황하게 반복적으로 작성하며 생성해야했던 부분을,

import SnapKit
import UIKit

class MainView: UIView {
    
    private let 대제목Label = LargeTitleLabel().createLabel(with: "대제목", color: .black)
    private let 소제목Label = SmallTitleLabel().createLabel(with: "소제목", color: .black)
    private let 본문Label = ContentLabel().createLabel(with: "본문", color: .black)
    .
    .
    .
    //기타 초기화 및 오토레이아웃 코드
}

이렇게 한 줄로 빠르게 작성할 수 있도록 하였다.

이로서 작업 속도가 빨라지고 실제로 팀원들에게서도 UI작업이 굉장히 편해졌다라는 피드백을 받았다.




그러나 뭔가 쎄한 느낌

import SnapKit
import UIKit

class MainView: UIView {
    
    private let 대제목Label = LargeTitleLabel().createLabel(with: "대제목", color: .black)
    private let 소제목Label = SmallTitleLabel().createLabel(with: "소제목", color: .black)
    private let 본문Label = ContentLabel().createLabel(with: "본문", color: .black)
    .
    .
    .
    //기타 초기화 및 오토레이아웃 코드
}
  1. 실제 사용 시, 각 레이블마다 레이블 클래스의 인스턴스를 계속 생성하는데 생성 이후에 더 이상 사용되지 않는다. 그 점에서 쓸 데없이 메모리를 많이 쓰는 것이 아닌가?

-> 일단 한 페이지에서 생성되는 레이블의 갯수가 적기 때문에 메모리 문제를 크게 일으키지는 않을 것으로 예상.
그러나 페이지가 복잡해졌을 때의 상황을 알아보고 싶다. 같은 방식으로 레이블 50개 정도를 생성해보고 테스트.


52개 레이블에 대해 계속 인스턴스를 생성하는 방식일때

한번만 생성하고 이후엔 재사용

확실히 아래쪽이 메모리 사용이 줄어들지만..

개발할 때 사용이 너무 귀찮아진다..!
레이블중에서도 3개만 뽑아서 이정도고 버튼이나 텍스트필드 기타 등등에 대해 모두 초기화를 해줘야한다.
이러면 원래의 편리하고자 했던 의미가 없어져버리는데?

크나큰 문제를 일으키지는 않는 것 같아서 일단은 처음방식으로 그냥 두고 더 고민해봐야곘다.

profile
오늘 배운걸 까먹었을 미래의 나에게..⭐️
post-custom-banner

0개의 댓글