아삭아삭 iOS 개발

[위클리 발표] Happy Realming 🤗(3)_background write 본문

카테고리 없음

[위클리 발표] Happy Realming 🤗(3)_background write

바닐라머스크 2022. 12. 20. 19:54

이번 포스팅에서는 relam의 background write에 다뤄보겠습니다~!

 

Part2) Background Write

  1. background realm example 

  2.(ver 10.26.0 이후) write.Async 등장

  3. writeAsync example

 

 


 

  1. background realm example 

realm 버전 10.26.0 이전까지는 background write 처리를 하기 위해서는 아래 2가지를 챙겨주어야 했습니다.

 

1) autoreleasepool 블록 안에 write 작업하기

autoreleasepool를 설정하면 블록내 코드가 자동으로 메모리 해제되는 것이 아니라,

모든 작업이 끝날 때 해제될 수 있도록 보장해줍니다.

 

이로인해 background 처리시 작업의 안정성을 높이기 위해 autoreleasepool을 사용해주는게 좋습니다.

 

2) 해당 블록 내에서 Realm()를 추가로 생성해서 접근하기

지난 포스팅 (1), (2)에서의 relam threading 규칙 3개transaction의 특징들을 이유로

background에서 write메서드 작업을 할 때에는 반드시 realm instance를 하나 더 생성해서 해당 object(메모리)로 조회해야 합니다.

 

아래는 작성해본 샘플 코드인데요

보시는 것처럼 DispatchQueue.global().async 블록 안에서 realm 인스턴스를 추가로 생성해서 peopleList 배열을 추가하고,

해당 코드들은 autoreleasepool에 담아서 처리해줬습니다.

 

  @objc func backgroundThreadAddTapped() {
  
        DispatchQueue.global().async {

            let otherRealm = try! Realm() // **중요** realm 인스턴스를 추가로 생성
            autoreleasepool { // 해당 블록내에서 write 작업을 하면 해당 코드가 메모리 해제 되는 것을 모든 작업을 마쳤을 때로 보장함
                
                for i in 0..<1000 { // 배열에 담아서 한 번에 추가하면 시간단축 가능
                    let developer = Developer(name: "SeSAC\(i)", age: i)
                    self.peopleList.append(developer)
                }
                
                try! otherRealm.write({ // **중요** 추가로 생성한 realm 인스턴스로 접근해서 처리
                    otherRealm.add(self.peopleList)
                })
                
            }
        }
    }

[전체코드 보러가기] 

 

  2. (ver 10.26.0 이후) write.Async 등장

그런데!! 조사를 하던 중, 버전 10.26.0부터는 아래처럼 writeAsync 메서드 자체를 realm에서 제공해주고 있다는 사실을 발견했습니다~!! 😆

writeAsync 메서드를 사용하면 위에 처음에 소개한 것처럼 autoreleasepool 블록이나, 추가로 realm instance를 생성해주는 등의 작업을 추가적으로 해주지 않아도 background에서 객체를 추가, 수정, 그리고 삭제까지 보다 간편하게 처리할 수 있습니다.

 

realm-swift Release notes

 

아래 writeAsync메서드의 정의를 보시면

beginAsyncWrite 내에서는 파라미터로 들어간 block()이 실행된 후, block내에서 포함하고 있는 액션들을 말그대로 asyncronously하게 실행합니다.

그리고 일련의 작업들이 commit되어 완료되거나 error로 실패하고 나면 그 이후에는 onComplete()이 호출되는 구조를 갖고 있습니다.

 

realm의 writeAsync definition 캡처

 

 

  3. writeAsync example

위에 1번에서 작성해본 예시와 동일한 기능을 하는 코드를 writeAsync로 수정해보았습니다.

이전과 달리 autoreleasepool 블록을 생성해줄 필요도 없고, 추가로 realm instance를 생성해주지 않아도 writeAsync로 작업이 가능하니 더 편리하게 background 작업 코드를 작성해볼 수 있겠죠?

    @objc func backgroundThreadAddWriteAsyncTapped() {
        
        for i in 0..<1000 {
            let developer = Developer(name: "SeSAC\(i)", age: i)
            self.peopleList.append(developer)
        }
        
        localRealm.writeAsync { // writeAsync로 바로 background 처리가 가능
            self.localRealm.add(self.peopleList)
        }
        
    }

[전체코드 보러가기] 

 

다음 포스팅에서는 이번 시리즈의 마지막으로 realm에서의 multiple thread 작업에 대해 추가 소개해보겠습니다!

 

 

 

< 참고자료 >

https://www.mongodb.com/docs/realm/sdk/swift/crud/threading/

 

Threading - Swift SDK — Realm

A realm instance is designed to work with one version at a time, not several different versions. Consider what Realm Database would have to do to support working with several different versions at once: it would need to store a potentially enormous graph t

www.mongodb.com

https://github.com/realm/realm-swift/blob/master/CHANGELOG.md#enhancements-3

 

GitHub - realm/realm-swift: Realm is a mobile database: a replacement for Core Data & SQLite

Realm is a mobile database: a replacement for Core Data & SQLite - GitHub - realm/realm-swift: Realm is a mobile database: a replacement for Core Data & SQLite

github.com