iOS 응용 (swift)
[iOS - swift] OptionSet에서 시프트 연산자를 사용하는 이유(Shift Operator)
jake-kim
2024. 9. 25. 01:18
OptionSet 개념
- OptionSet은 옵션이 있는 Set 자료구조이며, 옵션들을 마치 enum-case처럼 다룰 수 있고 set의 대표적인 연산자 insert, remove, contains, intersection 를 쓸 수 있는 자료구조
ex) UserSetting에 관한 플래그를 관리하는 OptionSet
struct UserSettingsFlags: OptionSet {
let rawValue: Int
static let darkMode = UserSettingsFlags(rawValue: 1 << 0)
static let notifications = UserSettingsFlags(rawValue: 1 << 1)
static let locationServices = UserSettingsFlags(rawValue: 1 << 2)
static let autoUpdate = UserSettingsFlags(rawValue: 1 << 3)
static let privacyMode = UserSettingsFlags(rawValue: 1 << 4)
static let sound = UserSettingsFlags(rawValue: 1 << 5)
static let vibration = UserSettingsFlags(rawValue: 1 << 6)
static let emailUpdates = UserSettingsFlags(rawValue: 1 << 7)
static let twoFactorAuthentication = UserSettingsFlags(rawValue: 1 << 8)
static let all: UserSettingsFlags = [
.darkMode,
.notifications,
.locationServices,
.autoUpdate,
.privacyMode,
.sound,
.vibration,
.emailUpdates,
.twoFactorAuthentication
]
}
OptionSet에서 rawValue를 bit로 표현하는 이유?
- 일반적으로 OptionSete에서는 rawValue를 보면 모두 shift연산자를 통해 표현
static let darkMode = UserSettingsFlags(rawValue: 1 << 0) // 0000 0001 (1)
static let notifications = UserSettingsFlags(rawValue: 1 << 1) // 0000 0010 (2)
static let locationServices = UserSettingsFlags(rawValue: 1 << 2) // 0000 0100 (4)
static let autoUpdate = UserSettingsFlags(rawValue: 1 << 3) // 0000 1000 (8)
static let privacyMode = UserSettingsFlags(rawValue: 1 << 4) // 0001 0000 (16)
static let sound = UserSettingsFlags(rawValue: 1 << 5) // 0010 0000 (32)
static let vibration = UserSettingsFlags(rawValue: 1 << 6) // 0100 0000 (64)
static let emailUpdates = UserSettingsFlags(rawValue: 1 << 7) // 1000 0000 (128)
static let twoFactorAuthentication = UserSettingsFlags(rawValue: 1 << 8) // 0001 0000 0000 (256)
* bit로 표현하는 이유?
- 1. 비트 OR, AND 연산을 통해 충돌 없이 다중 상태 표현하기가 용이
let option1 = 1 << 4 // 0001 0000 (16)
let option2 = 1 << 5 // 0010 0000 (32)
let combined = option1 | option2 // OR 연산: 0011 0000 (48)
- 2. 메모리 효율성
- bit대신에 Bool타입 flag를 사용할 경우 아래와 같이 8개가 있을 때, Bool하나에 1바이트가 필요하므로 총 8바이트가 필요
- 만약 bit로 표현하면 1바이트 필요
// 각각의 상태를 Bool로 관리할 경우
struct Settings {
var flag1: Bool = false
var flag2: Bool = false
var flag3: Bool = false
var flag4: Bool = false
var flag5: Bool = false
var flag6: Bool = false
var flag7: Bool = false
var flag8: Bool = false
}
- 3. 비트 연산은 하드웨어적으로 매우 빠른 연산
* 읽어보면 좋은 관련 글: OptionSet으로 flag 리펙토링하기 (플래그 관리, Bool대신 bit 사용하기)
* 참고