EEYatHo 앱 깎는 이야기

Swift ) Realm 사용시 쓰레드 주의사항 - EEYatHo iOS 본문

iOS, Swift

Swift ) Realm 사용시 쓰레드 주의사항 - EEYatHo iOS

EEYatHo 2021. 3. 23. 13:56
반응형

Realm을 처음 사용하면서,

객체를 참조하기만 해도 Realm에 접근하게 되며,

접근시 메인쓰레드가 아니면 안된다는 것을 알았습니다.

 

class NotificationManager {
	...
    func getAuthoState(enableHandler: (() -> ())? = nil, disableHandler: (() -> ())? = nil ) {
        UNUserNotificationCenter.current().getNotificationSettings { settings in
            switch settings.alertSetting {
            case .enabled:
                // 알림 권한이 있으면 enableHandler 실행
                if let enableHandler = enableHandler {
                    enableHandler()
                }
            default:
                // 알림 권한이 없으면 disableHandler 실행
                if let disableHandler = disableHandler {
                    disableHandler()
                }
            }
        }
    }
    ...
}

이렇게 NotificationManager에서 알람 권한 여부에 따라 분기하는 함수를 만들었고,

 

class AlermViewController: UIViewController {
    ...
    @objc func toggleSwitch(_ sender: UISwitch) {
        ...
        // Realm 에서 특정 인스턴스를 가져오는 소스
        ...
        NotificationManager.shared.getAuthoState {
            // Realm 에서 가져온 인스턴스를 사용하는 어떤 소스
        } disableHandler: {
            // Realm 에서 가져온 인스턴스를 사용하는 어떤 소스
        }
        ...
    }
    ...
}

위에서 만든 메소드를 이렇게 사용하려 했습니다.

 

그런데!

UNUserNotificationCenter.current().getNotificationSettings 는 무조건 서브 쓰레드로 빠지는 성질이 있기 때문에,

그 핸들러들도 서브 쓰레드로 실행이 되었고,

 

Realm에서 불러온 인스턴스를 사용하는 것 만으로도 Realm에 접근한 것이 되어버려서

이런 오류가 나왔고..

 

class AlermViewController: UIViewController {
    ...
    @objc func toggleSwitch(_ sender: UISwitch) {
        ...
        // Realm 에서 특정 인스턴스를 가져오는 소스
        ...
        NotificationManager.shared.getAuthoState {
            DispatchQueue.main.sync {
                // Realm 에서 가져온 인스턴스를 사용하는 어떤 소스
            }
        } disableHandler: {
            DispatchQueue.main.sync {
                // Realm 에서 가져온 인스턴스를 사용하는 어떤 소스
            }
        }
        ...
    }
    ...
}

이렇게 바꿔서 해결했습니다.

 

결론 

Realm 에 직접 CRUD를 할때만이 아니라,

Realm 에서 가져온 인스턴스를 다룰 때도 무조건 메인쓰레드로 하기!

Comments