2023. 11. 15. 17:30ㆍIOS [ 개념정리 ]
@Main 어트리뷰트는 Swift 5.5에서 도입된 새로운 어트리뷰트로,
비동기적인 작업 중에 메인 스레드에서 코드를 실행하도록 하는 역할을 한다.
이 어트리뷰트는 Swift concurrency 모델에서 사용되며, 특히 async 함수나 블록에서 메인 스레드에서 UI 업데이트와 같은 작업을 수행할 때 유용하다.
예시 코드 👇
import UIKit
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
fetchDataAndUIUpdate()
}
func fetchDataAndUIUpdate() {
// 백그라운드에서 비동기적으로 데이터를 가져옴
Task {
let data = await fetchData()
// @Main 어트리뷰트를 사용하여 메인 스레드에서 UI 업데이트
@MainActor
func updateUI() {
// UI 업데이트 코드
self.updateUI(with: data)
}
// UI 업데이트를 메인 스레드에서 실행
updateUI()
}
}
func fetchData() async -> Data {
// 비동기적으로 데이터를 가져오는 코드
// ...
}
func updateUI(with data: Data) {
// UI 업데이트 코드
// ...
}
}
@Main 어트리뷰트를 사용하면 updateUI() 함수가 메인 스레드에서 실행되도록 보장된다.
이렇게 함으로써 메인 스레드에서만 수행되어야 하는 UI 업데이트 코드를 명시적으로 표현할 수 있다.
자 그럼 여기서 말하는 메인스레드가 무엇이며 , 왜 메인스레드에서 실행해야하는 경우가 생길까?
메인스레드의 정의는 대략적으로 다음과 같다.
UI 이벤트 처리: 사용자의 터치, 제스처, 키 입력 등과 같은 UI 이벤트를 처리한다.
이러한 이벤트는 주로 메인 스레드에서 발생하고 처리된다.
UI 업데이트: 화면에 표시되는 내용을 갱신하거나 애니메이션을 처리하는 작업은 메인 스레드에서 이루어진다.
UIKit (iOS) 및 AppKit (macOS) 프레임워크에서 제공되는 UI 컴포넌트들은 메인 스레드에서만 안전하게 조작할 수 있다.
이벤트 루프 처리: 앱의 이벤트 루프(Event Loop)는 사용자 인터랙션 및 시스템 이벤트를 기다리고, 해당 이벤트에 대한 응답을 처리한다. 메인 스레드는 이 이벤트 루프를 실행하며 UI 이벤트 및 기타 이벤트를 처리한다.
앱 라이프사이클 관리: 앱의 시작, 종료, 백그라운드 진입 등과 같은 라이프사이클 이벤트를 처리한다.
데이터 모델 업데이트: 주로 메인 스레드에서 앱의 데이터 모델을 업데이트하고, 데이터 변경에 따른 UI 갱신을 수행한다.
그리고 메인스레드에서 실행하는 이유는 다음과같다.
UI 업데이트: iOS 및 macOS에서 UI는 메인 스레드에서만 업데이트 된다.
따라서 UI 업데이트 코드는 메인 스레드에서 실행되어야 한다.
다른 스레드에서 UI를 직접 조작하면 예측할 수 없는 동작이 발생할 수 있으며, 앱의 안정성이 감소할 수 있다.
애니메이션 및 사용자 상호 작용: 사용자가 앱과 상호 작용할 때 발생하는 이벤트 및 애니메이션은 주로 메인 스레드에서 처리된다.
메인 스레드에서 처리되지 않으면 앱의 응답성이 저하되고 사용자 경험이 나빠질 수 있다.
코어 데이터 및 기타 UI 프레임워크: 코어 데이터(Core Data)와 같은 UI 프레임워크는 주로 메인 스레드에서 동작한다.
이러한 프레임워크를 사용하는 작업은 메인 스레드에서 실행해야 한다.
UIKit 및 AppKit 메서드 호출: iOS의 UIKit 및 macOS의 AppKit은 대부분의 UI 관련 메서드를 메인 스레드에서 실행해야한다.
이 규칙을 지키지 않으면 예기치 않은 결과가 발생할 수 있다.
이러한 점들을 보았을때 , 메인스레드는 화면에 데이터를 실시간 반영하거나 ,
이벤트에 대한 응답 , 라이프사이클 진행등등을 진행하는 곳이기 때문에
다른곳에서 해당기능을 사용할시에 문제가 생길 수 있음을 야기할 수 있어
메인스레드에서 UI의 변화같은것을 진행시켜야하는것같다.
.
.
.
IOS 에서 메모리를 최적화 하는 방법은 무엇들이있을까 ?
1. ARC (Automatic Reference Counting): Swift 및 Objective-C에서는 자동으로 객체의 수명을 관리하는 ARC를 제공한다.
수동으로 메모리를 할당하고 해제하는 대신에 ARC를 사용하여 불필요한 객체 참조를 방지하고 메모리 누수를 줄일 수 있다.
첫번째로는 저번에 공부한 ARC이다 .
swift에 자동으로 탑재된 기능으로 , 쓰이는 메모리는 활성화하고 쓰이지않는 메모리를 비활성화하는등의 기능으로
쓸데없는 메모리 누수를 줄여준다.
2. 강한 순환 참조 해결: Delegate 패턴이나 클로저에서의 강한 순환 참조를 피하려고 해야한다.
약한(weak) 참조나 비소유(unowned) 참조를 사용하여 순환 참조 문제를 방지할 수 있다.
두번째로는 강한 순환참조를 지양하는것이다.
강한 순환참조를 무분별하게 사용한다면 순환참조의 끝없는 진행으로
메모리가 계속 활성화되어있을 수 있기때문에 , 누수를 막기위해서는 코드를 잘 짜야한다.
3. Lazy Loading 및 적절한 데이터 로딩: 화면에 표시되지 않는 데이터는 필요할 때까지 로딩하지 않고, 필요한 경우에만 로딩하는 "게으른 로딩"을 사용.
또한, 대용량 데이터를 다룰 때는 페이징(paging)이나 스트리밍과 같은 기술을 사용하여 필요한 부분만 로딩.
세번째로는 Lazy Loading이다.
예를들어 트위터를 열면 , 내 알고리즘 게시물이 스크롤할때마다 쭈루룩 계속 나오는것을 볼 수 있다.
그러나 트위터 같은 큰 대기업 어플이 이런 미리보기 메모리를 한번에 짠 하고 다 띄워놓았다면 ,
메모리 누수로인해 앱의 성능저하가 심할것을 예상했을거고,
그런 방지책으로 설정해둔것이 페이지네이션 기술이다.
페이지네이션 기술을 통해 , 드래그했을때 로딩창을띄우고 일정량의 게시물 데이터를 받아오는식으로 메모리 누수를 막았다.
4. 캐싱 활용: 이미 로딩한 데이터나 이미지 등을 캐시에 저장하여 필요할 때 재사용함으로써 네트워크 호출이나 불필요한 데이터 로딩을 줄일 수 있다.
네번째로는 캐싱이다.
어플을 키면 늘 띄워주는 데이터들이 있을텐데 , 그 데이터들을 매번 받아와서 로딩한다면 그것조차 어플의 효율성을 떨어트리는 행위이다.
그래서 거의 모든 프로그래밍된 프로그램들은 캐싱기술을 활용하는데 , 한번 본 데이터를 캐시에 저장하여 다시 그페이지를 본다면
캐시를 재사용해 불필요한 데이터로딩 / 네트워크 호출을 줄이고 메모리관리를 용이하게 하는것이다.
.
.
.
고차함수 (map, filter, reduce) 의 개념.
map
배열의 모든 요소에 함수를 적용하여 변환된 새로운 배열을 생성.
👇
( 1x1, 2x2, 3x3, 4x4, 5x5 한번씩 거쳐가는 코드 )
let numbers = [1, 2, 3, 4, 5]
let squaredNumbers = numbers.map { $0 * $0 }
print(squaredNumbers) // 출력: [1, 4, 9, 16, 25]
filter
배열의 요소 중에서 특정 조건을 만족하는 요소만을 걸러낸 새로운 배열을 생성.
👇
( 1,2,3,4,5 중 2로나누었을때 나머지가 0인 수를 필터링 )
let evenNumbers = numbers.filter { $0 % 2 == 0 }
print(evenNumbers) // 출력: [2, 4]
reduce
배열의 요소들을 하나의 값으로 축약(reduce)한다.
초기값과 클로저를 사용하여 각 요소를 결합.
👇
( 1,2,3,4,5 의 배열에서 index값 0 1 2 3 4 를 차례대로 더해준 값 )
let sum = numbers.reduce(0) { $0 + $1 }
print(sum) // 출력: 15
'IOS [ 개념정리 ]' 카테고리의 다른 글
23.11.16 딕셔너리(Dictionary), 집합(Set), 배열(Array)의 개념 (0) | 2023.11.17 |
---|---|
23.11.10 hugging과 resistance의 개념정리 / 뷰 컨트롤러의 라이프 사이클 개념정리 (0) | 2023.11.10 |
23.11.09 ARC 개념정리 / TableVie 개념정리 (1) | 2023.11.09 |
23.11.08 앱의 상태 / 스토리보드를 이용할때의 장단점 (0) | 2023.11.08 |
23.11.1 옵셔널(Optional)의 개념과 확장(Extension)의 개념 (1) | 2023.11.01 |