Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

์Šค๋ ˆ๋”ฉ - Swift SDK

์ด ํŽ˜์ด์ง€์˜ ๋‚ด์šฉ

  • ๋”ฐ๋ผ์•ผ ํ•  ์„ธ ๊ฐ€์ง€ ๊ทœ์น™
  • ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์“ฐ๊ธฐ ์ˆ˜ํ–‰
  • ๋น„๋™๊ธฐ ์“ฐ๊ธฐ๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ
  • ๋น„๋™๊ธฐ ์“ฐ๊ธฐ ์ปค๋ฐ‹ ๋˜๋Š” ์ทจ์†Œ
  • ์Šค๋ ˆ๋“œ ๊ฐ„ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜
  • ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ Realm์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์ง๋ ฌ ๋Œ€๊ธฐ์—ด ๋งŒ๋“ค๊ธฐ
  • ์Šค๋ ˆ๋“œ ๊ฐ„ ์ธ์Šคํ„ด์Šค ์ „๋‹ฌ
  • ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ๋™์ผํ•œ Realm ์‚ฌ์šฉ
  • Realm ์ƒˆ๋กœ๊ณ ์นจ
  • ๋™๊ฒฐ๋œ ๊ฐ์ฒด
  • Realm์˜ ์Šค๋ ˆ๋”ฉ ๋ชจ๋ธ ์‹ฌ์ธต ๋ถ„์„
  • Git๊ณผ ๋น„๊ต ๋ฐ ๋Œ€์กฐ
  • ๋‚ด๋ถ€ ๊ตฌ์กฐ
  • ์š”์•ฝ
  • ์ „์†ก ๊ฐ€๋Šฅ, ์ „์†ก ๋ถˆ๊ฐ€๋Šฅ ๋ฐ ์Šค๋ ˆ๋“œ ์ œํ•œ ์œ ํ˜•

iOS ๋ฐ tvOS ์•ฑ์„ ๋น ๋ฅด๊ณ  ์‘๋‹ต์„ฑ์ด ๋›ฐ์–ด๋‚˜๊ฒŒ ๋งŒ๋“ค๋ ค๋ฉด ์‹œ๊ฐ ์ž๋ฃŒ๋ฅผ ๋ฐฐ์น˜ํ•˜๊ณ  ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ปดํ“จํŒ… ์‹œ๊ฐ„๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์‹œ๊ฐ„์˜ ๊ท ํ˜•์„ ๋งž์ถฐ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์•ฑ ๊ฐœ๋ฐœ์ž๋Š” ๋ชจ๋“  ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ๊ด€๋ จ ์ž‘์—…์„ ์œ„ํ•œ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ ๋˜๋Š” UI ์Šค๋ ˆ๋“œ, ํ”„๋ ˆ์  ํ…Œ์ด์…˜์„ ์œ„ํ•ด UI ์Šค๋ ˆ๋“œ๋กœ ์ „์†กํ•˜๊ธฐ ์ „์— ๋” ๋งŽ์€ ์›Œํฌ๋กœ๋“œ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ ๋“ฑ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋กœ ์ž‘์—…์„ ๋ถ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ๋งŽ์€ ์ž‘์—…์„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ๋กœ ์˜คํ”„๋กœ๋“œํ•จ์œผ๋กœ์จ UI ์Šค๋ ˆ๋“œ๋Š” ์›Œํฌ๋กœ๋“œ์˜ ํฌ๊ธฐ์™€ ์ƒ๊ด€์—†์ด ๋†’์€ ๋ฐ˜์‘์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ต์ฐฉ ์ƒํƒœ ๋ฐ ๊ฒฝ์Ÿ ์ƒํƒœ์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๋ฉด์„œ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๊ณ  ์„ฑ๋Šฅ์ด ๋›ฐ์–ด๋‚˜๋ฉฐ ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Realm์€ ์ด ๊ณผ์ •์„ ๊ฐ„์†Œํ™”ํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

ํŒ

๋‹ค์Œ๋„ ์ฐธ์กฐํ•˜์„ธ์š”.

10.26.0 ๊ธฐ์ค€์œผ๋กœ, Realm ์€ ๋ฐฐ๊ฒฝ ์“ฐ๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋น„๋™๊ธฐ ์“ฐ๊ธฐ (write) ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์“ฐ๊ธฐ ์ˆ˜ํ–‰์„ ์ฐธ์กฐํ•˜์„ธ์š”. ๋น„๋™๊ธฐ ์“ฐ๊ธฐ (write) ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šค๋ ˆ๋“œ ์„ธ์ดํ”„ ์ฐธ์กฐ ๋˜๋Š” ๋™๊ฒฐ๋œ ๊ฐ์ฒด ๋ฅผ ์ „๋‹ฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€์—์„œ๋Š” ์Šค๋ ˆ๋“œ ์ „์ฒด์—์„œ ์˜์—ญ ํŒŒ์ผ๊ณผ ๊ฐ์ฒด๋ฅผ ์ˆ˜๋™์œผ๋กœ ๊ด€๋ฆฌ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. Realm ์€ Swift ํ–‰์œ„์ž ์‚ฌ์šฉ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. Swift ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜์—ญ ์•ก์„ธ์Šค ๋ฅผ ๊ด€๋ฆฌ ํ•ฉ๋‹ˆ๋‹ค. Realm์˜ ํ–‰์œ„์ž ์ง€์› ์— ๋Œ€ํ•œ ๊ฐœ์š”๋Š” ํ–‰์œ„์ž์™€ Realm ์‚ฌ์šฉ - Swift SDK ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์•ฑ์„ ์œ„ํ•œ Realm์˜ ๋„๊ตฌ๋ฅผ ์‚ดํŽด๋ณด๊ธฐ ์ „์— ๋‹ค์Œ ์„ธ ๊ฐ€์ง€ ๊ทœ์น™์„ ์ดํ•ดํ•˜๊ณ  ๋”ฐ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฝ๊ธฐ ์œ„ํ•ด ๋ฝํ•˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
Realm์˜ MVCC(Multiversion Concurrency Control) ์•„ํ‚คํ…์ฒ˜๋Š” ์ฝ๊ธฐ ์ž‘์—…์„ ์ž ๊ธ€ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ฝ์€ ๊ฐ’์€ ์ ˆ๋Œ€๋กœ ์†์ƒ๋˜๊ฑฐ๋‚˜ ๋ถ€๋ถ„์ ์œผ๋กœ ์ˆ˜์ •๋œ ์ƒํƒœ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž ๊ธˆ์ด๋‚˜ ๋ฎคํ…์Šค ์—†์ด๋„ ๋ชจ๋“  ์Šค๋ ˆ๋“œ์—์„œ ๋™์ผํ•œ Realm ํŒŒ์ผ์„ ์ž์œ ๋กญ๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ์ฝ๊ธฐ ์ „์— ์ฐจ๋ก€๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผ ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์ž ๊ทธ๋Š” ๊ฒƒ์€ ์„ฑ๋Šฅ ๋ณ‘๋ชฉ ํ˜„์ƒ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์ž‘์„ฑํ•˜๋Š” ๊ฒฝ์šฐ UI ์Šค๋ ˆ๋“œ์—์„œ ๋™๊ธฐ์‹ ์“ฐ๊ธฐ๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.
๋ชจ๋“  ์Šค๋ ˆ๋“œ์—์„œ Realm ํŒŒ์ผ์— ์“ธ ์ˆ˜ ์žˆ์ง€๋งŒ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์ž‘์„ฑ์ž๋งŒ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋™๊ธฐ์‹ ์“ฐ๊ธฐ ํŠธ๋žœ์žญ์…˜(write transaction)์€ ์„œ๋กœ๋ฅผ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. UI ์Šค๋ ˆ๋“œ์—์„œ ๋™๊ธฐ์‹ ์“ฐ๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์“ฐ๊ธฐ๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ ์•ฑ์ด ์‘๋‹ตํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Device Sync ๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์“ฐ๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ ๋™๊ธฐํ™”๋œ Realm์ด ์žˆ๋Š” UI ์Šค๋ ˆ๋“œ์—์„œ๋Š” ๋™๊ธฐ์‹ ์“ฐ๊ธฐ๋ฅผ ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๋ผ์ด๋ธŒ ๊ฐ์ฒด, ์ปฌ๋ ‰์…˜ ๋˜๋Š” ์˜์—ญ์„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์— ์ „๋‹ฌํ•˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
๋ผ์ด๋ธŒ ๊ฐ์ฒด, ์ปฌ๋ ‰์…˜ ๋ฐ Realm ์ธ์Šคํ„ด์Šค๋Š” ์Šค๋ ˆ๋“œ์— ํ•œ์ •๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ํ•ด๋‹น ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋œ ์Šค๋ ˆ๋“œ์—์„œ๋งŒ ์œ ํšจํ•ฉ๋‹ˆ๋‹ค. ์‹ค์งˆ์ ์œผ๋กœ ์ด๋Š” ๋ผ์ด๋ธŒ ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Realm์€ ์Šค๋ ˆ๋“œ ๊ฐ„์— ๊ฐ์ฒด๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ํŒ

๋‹ค์Œ๋„ ์ฐธ์กฐํ•˜์„ธ์š”.

๋ฒ„์ „ 10.26.0์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ

writeAsync๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๊ฐ์ฒด๋ฅผ ์ถ”๊ฐ€, ์ˆ˜์ • ๋˜๋Š” ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

writeAsync ์„ ์‚ฌ์šฉํ•˜๋ฉด ์Šค๋ ˆ๋“œ ์„ธ์ดํ”„ ์ฐธ์กฐ ๋˜๋Š” ๋™๊ฒฐ๋œ ๊ฐ์ฒด ๋ฅผ ์ „๋‹ฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  realm.writeAsync ์„(๋ฅผ) ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์“ฐ๊ธฐ๊ฐ€ ์™„๋ฃŒ๋˜๊ฑฐ๋‚˜ ์‹คํŒจํ•œ ํ›„ ์†Œ์Šค ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰ํ•  ๋ฉ”์„œ๋“œ์— ์™„๋ฃŒ ์ฐจ๋‹จ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐฑ๊ทธ๋ผ์šด๋“œ ์“ฐ๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•  ๋•Œ ๊ณ ๋ คํ•ด์•ผ ํ•  ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

  • ๋น„๋™๊ธฐ ์“ฐ๊ธฐ ์ฐจ๋‹จ์€ ์˜์—ญ์„ ๋‹ซ๊ฑฐ๋‚˜ ๋ฌดํšจํ™”ํ•ฉ๋‹ˆ๋‹ค.

  • ํŠธ๋žœ์žญ์…˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์ปค๋ฐ‹ํ•˜๊ฑฐ๋‚˜ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let realm = try! Realm()
// Query for a specific person object on the main thread
let people = realm.objects(Person.self)
let thisPerson = people.where {
$0.name == "Dachary"
}.first
// Perform an async write to add dogs to that person's dog list.
// No need to pass a thread-safe reference or frozen object.
realm.writeAsync {
thisPerson?.dogs.append(objectsIn: [
Dog(value: ["name": "Ben", "age": 13]),
Dog(value: ["name": "Lita", "age": 9]),
Dog(value: ["name": "Maui", "age": 1])
])
} onComplete: { _ in
// Confirm the three dogs were successfully added to the person's dogs list
XCTAssertEqual(thisPerson!.dogs.count, 3)
// Query for one of the dogs we added and see that it is present
let dogs = realm.objects(Dog.self)
let benDogs = dogs.where {
$0.name == "Ben"
}
XCTAssertEqual(benDogs.count, 1)
}

SDK๋Š” ์˜์—ญ ์ด ํ˜„์žฌ ๋น„๋™๊ธฐ ์“ฐ๊ธฐ (write) ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” Bool ์„(๋ฅผ) ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. isPerformingAsynchronousWriteOperations ๋ณ€์ˆ˜๋Š” ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜๋ฅผ ํ˜ธ์ถœํ•œ ํ›„ true ์ด(๊ฐ€) ๋ฉ๋‹ˆ๋‹ค.

  • writeAsync

  • beginAsyncWrite

  • commitAsyncWrite

์˜ˆ์•ฝ๋œ ๋ชจ๋“  ๋น„๋™๊ธฐ ์“ฐ๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์ด ์ƒํƒœ๊ฐ€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์˜์—ญ์ด ๋‹ซํžˆ๊ฑฐ๋‚˜ ๋ฌดํšจํ™”๋˜๋Š” ๊ฒƒ์€ ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค.

๋น„๋™๊ธฐ ์“ฐ๊ธฐ๋ฅผ ์™„๋ฃŒํ•˜๋ ค๋ฉด ์‚ฌ์šฉ์ž ๋˜๋Š” SDK๊ฐ€ ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

writeAsync ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด SDK๊ฐ€ ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ๋˜๋Š” ์ทจ์†Œ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐ์ฒด ๋ฒ”์œ„์— ์—ฐ๊ฒฐ๋œ ์ƒํƒœ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์œ ์ง€ํ•  ํ•„์š” ์—†์ด ๋น„๋™๊ธฐ ์“ฐ๊ธฐ์˜ ํŽธ๋ฆฌํ•จ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ writeAsync ์ฐจ๋‹จ ์ค‘์— ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ commitAsyncWrite cancelAsyncWrite์„(๋ฅผ) ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฉ”์„œ๋“œ ์ค‘ ํ•˜๋‚˜๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ๋ฐ˜ํ™˜ํ•˜๋ฉด writeAsync๋„ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

  • ์“ฐ๊ธฐ ์ฐจ๋‹จ์˜ ์ง€์นจ์„ ์‹คํ–‰ํ•œ ํ›„ ์“ฐ๊ธฐ๋ฅผ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค.

  • ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ writeAsync ์ž‘์—…์ด ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

๋น„๋™๊ธฐ ์“ฐ๊ธฐ ํŠธ๋žœ์žญ์…˜(write transaction)์„ ์ปค๋ฐ‹ํ•˜๊ฑฐ๋‚˜ ์ทจ์†Œํ•  ์‹œ๊ธฐ๋ฅผ ๋” ํšจ๊ณผ์ ์œผ๋กœ ์ œ์–ดํ•˜๋ ค๋ฉด beginAsyncWrite ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํŠธ๋žœ์žญ์…˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์ปค๋ฐ‹ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ ์“ฐ๊ธฐ๋ฅผ ์ปค๋ฐ‹ํ•˜์ง€ ์•Š๊ณ  ๋ฐ˜ํ™˜ํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜์ด ์ทจ์†Œ๋ฉ๋‹ˆ๋‹ค. beginAsyncWrite์€(๋Š”) cancelAsyncWrite์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ID๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

commitAsyncWrite ์“ฐ๊ธฐ ํŠธ๋žœ์žญ์…˜(write transaction)์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์˜์—ญ์— ์œ ์ง€ํ•˜๋Š” ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค. commitAsyncWrite์€(๋Š”) onComplete ๋ธ”๋ก์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ฐจ๋‹จ์€ ์ปค๋ฐ‹์ด ์™„๋ฃŒ๋˜๊ฑฐ๋‚˜ ์˜ค๋ฅ˜๋กœ ์ธํ•ด ์‹คํŒจํ•˜๋ฉด ์†Œ์Šค ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

commitAsyncWrite์„(๋ฅผ) ํ˜ธ์ถœํ•˜๋ฉด ์ฆ‰์‹œ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด SDK๊ฐ€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ I/O๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋™์•ˆ ํ˜ธ์ถœ์ž๊ฐ€ ๊ณ„์† ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฉ”์†Œ๋“œ๋Š” cancelAsyncWrite์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ID๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ณด๋ฅ˜ ์ค‘์ธ ์™„๋ฃŒ ์ฐจ๋‹จ ํ˜ธ์ถœ์ด ์ทจ์†Œ๋ฉ๋‹ˆ๋‹ค. ์ปค๋ฐ‹ ์ž์ฒด๋ฅผ ์ทจ์†Œํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

commitAsyncWrite์— ๋Œ€ํ•œ ์ˆœ์ฐจ์  ํ˜ธ์ถœ์„ ๊ทธ๋ฃนํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๋ฐฐ์น˜๋œ ํŠธ๋žœ์žญ์…˜์ด ์ž‘์€ ๊ฒฝ์šฐ ์ด๋Ÿฌํ•œ ํ˜ธ์ถœ์„ ๋ฐฐ์น˜ํ•˜๋ฉด ์“ฐ๊ธฐ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค. ํŠธ๋žœ์žญ์…˜ ๊ทธ๋ฃนํ™”๋ฅผ ํ—ˆ์šฉํ•˜๋ ค๋ฉด isGroupingAllowed ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ true(์œผ)๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

beginAsyncWrite ๋˜๋Š” commitAsyncWrite์—์„œ cancelAsyncWrite์„(๋ฅผ) ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. beginAsyncWrite์—์„œ ํ˜ธ์ถœํ•˜๋ฉด ์ „์ฒด ์“ฐ๊ธฐ ํŠธ๋žœ์žญ์…˜(write transaction)์ด ์ทจ์†Œ๋ฉ๋‹ˆ๋‹ค. commitAsyncWrite์—์„œ ํ˜ธ์ถœํ•˜๋ฉด commitAsyncWrite์— ์ „๋‹ฌํ–ˆ์„ ์ˆ˜ ์žˆ๋Š” onComplete ์ฐจ๋‹จ๋งŒ ์ทจ์†Œ๋ฉ๋‹ˆ๋‹ค. ์ปค๋ฐ‹ ์ž์ฒด๋ฅผ ์ทจ์†Œํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์ทจ์†Œํ•˜๋ ค๋Š” beginAsyncWrite ๋˜๋Š” commitAsyncWrite์˜ ID๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ๋™์ผํ•œ Realm ํŒŒ์ผ์— ์•ก์„ธ์Šคํ•˜๋ ค๋ฉด ์•ก์„ธ์Šค๊ฐ€ ํ•„์š”ํ•œ ๋ชจ๋“  ์Šค๋ ˆ๋“œ์—์„œ ์˜์—ญ ์ธ์Šคํ„ด์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋™์ผํ•œ ๊ตฌ์„ฑ์„ ์ง€์ •ํ•˜๋Š” ํ•œ ๋ชจ๋“  ์˜์—ญ ์ธ์Šคํ„ด์Šค๋Š” ๋””์Šคํฌ์˜ ๋™์ผํ•œ ํŒŒ์ผ์— ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค.

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ Realm์œผ๋กœ ์ž‘์—…ํ•  ๋•Œ ์ฃผ์š” ๊ทœ์น™ ์ค‘ ํ•˜๋‚˜๋Š” ๊ฐ์ฒด๋Š” ์Šค๋ ˆ๋“œ์— ํ•œ์ •๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์‹œ์ž‘๋œ Realm, ์ปฌ๋ ‰์…˜ ๋˜๋Š” ๊ฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. Realm์˜ MVCC(Multiversion Concurrency Control) ์•„ํ‚คํ…์ฒ˜๋Š” ๊ฐ์ฒด์˜ ํ™œ์„ฑ ๋ฒ„์ „์ด ์–ธ์ œ๋“ ์ง€ ์—ฌ๋Ÿฌ ๊ฐœ์ผ ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ ์ œํ•œ์€ ํ•ด๋‹น ์Šค๋ ˆ๋“œ์˜ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๊ฐ€ ๋™์ผํ•œ ๋‚ด๋ถ€ ๋ฒ„์ „์ธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ ๊ฐ„์— ํ†ต์‹ ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋”ฐ๋ผ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋‘ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ์—์„œ ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๋ฉด ๋‘ ์Šค๋ ˆ๋“œ ๋ชจ๋‘์—์„œ ๊ฐ์ฒด๋ฅผ ์ฟผ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • ์Šค๋ ˆ๋“œ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€์‘ํ•˜๋ ค๋ฉด Realm์˜ ์•Œ๋ฆผ์„์‚ฌ์šฉํ•˜์„ธ์š”.

  • ํ˜„์žฌ ์Šค๋ ˆ๋“œ์˜ ์˜์—ญ ์ธ์Šคํ„ด์Šค์— ์žˆ๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์ผ์–ด๋‚œ ๋ณ€ํ™”๋ฅผ ๋ณด๋ ค๋ฉด ์˜์—ญ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒˆ๋กœ ๊ณ ์นจํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฐ์ฒด์˜ ๋น ๋ฅธ ์ฝ๊ธฐ ์ „์šฉ ๋ณด๊ธฐ๋ฅผ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋กœ ๋ณด๋‚ด๋ ค๋ฉด ๊ฐ์ฒด๋ฅผ '๋™๊ฒฐ'ํ•ฉ๋‹ˆ๋‹ค.

  • ์•ฑ์—์„œ ๊ฐ์ฒด์˜ ๋งŽ์€ ์ฝ๊ธฐ ์ „์šฉ ๋ทฐ๋ฅผ ์œ ์ง€ํ•˜๊ณ  ๊ณต์œ ํ•˜๋ ค๋ฉด ์˜์—ญ์—์„œ ๊ฐ์ฒด๋ฅผ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.

  • Realm ๋˜๋Š” ํŠน์ • ๊ฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์™€ ๊ณต์œ ํ•˜๊ฑฐ๋‚˜ ํ–‰์œ„์ž ๊ฒฝ๊ณ„๋ฅผ ๋„˜์–ด ๊ณต์œ ํ•˜๋ ค๋ฉด Realm ์ธ์Šคํ„ด์Šค ๋˜๋Š” ๊ฐ์ฒด์— ๋Œ€ํ•œ ์Šค๋ ˆ๋“œ ์„ธ์ดํ”„ ์ฐธ์กฐ ๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ ์€ ThreadSafeReference ์ „๋‹ฌ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ Realm์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ง๋ ฌ ๋Œ€๊ธฐ์—ด์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. Realm์€ global() ๋Œ€๊ธฐ์—ด๊ณผ ๊ฐ™์€ ๋™์‹œ ๋Œ€๊ธฐ์—ด์—์„œ์˜ ์˜์—ญ ์‚ฌ์šฉ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

// Initialize a serial queue, and
// perform realm operations on it
let serialQueue = DispatchQueue(label: "serial-queue")
serialQueue.async {
let realm = try! Realm(configuration: .defaultConfiguration, queue: serialQueue)
// Do something with Realm on the non-main thread
}

Realm, Results, List ๋ฐ ๊ด€๋ฆฌ๋˜๋Š” Objects ์ธ์Šคํ„ด์Šค๋Š” ์Šค๋ ˆ๋“œ๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํ•ด๋‹น ํ•ญ๋ชฉ์„ ๋งŒ๋“  ์Šค๋ ˆ๋“œ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Realm์€ ์Šค๋ ˆ๋“œ ์„ธ์ดํ”„ ์ฐธ์กฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•˜์—ฌ ํ•œ ์Šค๋ ˆ๋“œ์—์„œ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋กœ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฒ„์ „ 10.20.0์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ: @ThreadSafe ๋ž˜ํผ(wrapper) ๋ฐ ThreadSafeReference๋Š” Sendable์„ Sendable ์ค€์ˆ˜ํ•ฉ๋‹ˆ๋‹ค.

Swift ์ด์ƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ 5.6 @ThreadSafe ์†์„ฑ ๋ž˜ํผ ์™€ ThreadSafeReference ๊ฐ€ ๋ชจ๋‘ Sendable์„ ์ค€์ˆ˜ํ•ฉ๋‹ˆ๋‹ค.

๋ฒ„์ „ 10.17.0์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์Šค๋ ˆ๋“œ์— ํ•œ์ •๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. @ThreadSafe ์†์„ฑ ๋ž˜ํผ(wrapper)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›๋ณธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๋‹น์—ฐํžˆ @ThreadSafe ๋ž˜ํ•‘๋œ ๋ณ€์ˆ˜๋Š” ํ•ญ์ƒ ์„ ํƒ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

  2. @ThreadSafe ๋ž˜ํ•‘๋œ ๋ณ€์ˆ˜๋ฅผ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

  3. ๋‹ค๋ฅธ ์„ ํƒ์‚ฌํ•ญ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ @ThreadSafe ๋ž˜ํ•‘๋œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. ๋งŒ์•ฝ ์ฐธ์กฐ๋œ ๊ฐ์ฒด๊ฐ€์˜์—ญ์—์„œ ์ œ๊ฑฐ๋˜๋ฉด ์ฐธ์กฐํ•˜๋Š” ๋ณ€์ˆ˜๋Š” nil์ด ๋ฉ๋‹ˆ๋‹ค.

let realm = try! Realm()
let person = Person(name: "Jane")
try! realm.write {
realm.add(person)
}
// Create thread-safe reference to person
@ThreadSafe var personRef = person
// @ThreadSafe vars are always optional. If the referenced object is deleted,
// the @ThreadSafe var will be nullified.
print("Person's name: \(personRef?.name ?? "unknown")")
// Pass the reference to a background thread
DispatchQueue(label: "background", autoreleaseFrequency: .workItem).async {
let realm = try! Realm()
try! realm.write {
// Resolve within the transaction to ensure you get the
// latest changes from other threads. If the person
// object was deleted, personRef will be nil.
guard let person = personRef else {
return // person was deleted
}
person.name = "Jane Doe"
}
}

๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ๊ฐ์ฒด๋กœ ์ž‘์—…ํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ํ•ด๋‹น ์Šค๋ ˆ๋“œ์—์„œ ๊ฐ์ฒด๋ฅผ ๋‹ค์‹œ ์ฟผ๋ฆฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ์ฒด์— ํ”„๋ผ์ด๋จธ๋ฆฌ ํ‚ค๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ์ด๋ฅผ ์ฟผ๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ํ‚ค๊ฐ€ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๊ด€๊ณ„์—†์ด ๋ชจ๋“  ๊ฐ์ฒด์— @ThreadSafe ๋ž˜ํผ(wrapper)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์‹œ

๋‹ค์Œ ์˜ˆ์—์„œ๋Š” ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜์— @ThreadSafe๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด๋Š” ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋˜๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํŒ

์•ฑ์ด async/await ์ปจํ…์ŠคํŠธ์—์„œ Realm์— ์•ก์„ธ์Šคํ•˜๋Š” ๊ฒฝ์šฐ ์ฝ”๋“œ๋ฅผ @MainActor(์œผ)๋กœ ํ‘œ์‹œํ•˜์—ฌ ์Šค๋ ˆ๋“œ ๊ด€๋ จ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

func someLongCallToGetNewName() async -> String {
return "Janet"
}
@MainActor
func loadNameInBackground(@ThreadSafe person: Person?) async {
let newName = await someLongCallToGetNewName()
let realm = try! await Realm()
try! realm.write {
person?.name = newName
}
}
@MainActor
func createAndUpdatePerson() async {
let realm = try! await Realm()
let person = Person(name: "Jane")
try! realm.write {
realm.add(person)
}
await loadNameInBackground(person: person)
}
await createAndUpdatePerson()

Realm Swift SDK ๋ฒ„์ „ 10.17.0 ์ด์ „ ๋˜๋Š” ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์Šค๋ ˆ๋“œ์— ํ•œ์ •๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์Šค๋ ˆ๋“œ์— ํ•œ์ •๋œ ๊ฐ์ฒด๋กœ ThreadSafeReference๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

  2. ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ ๋˜๋Š” ๋Œ€๊ธฐ์—ด์— ์ฐธ์กฐ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

  3. Realm.resolve(_:) ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ Realm์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋œ ๊ฐ์ฒด๋ฅผ ์ •์ƒ์ ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ค‘์š”

ThreadSafeReference๋Š” ์ •ํ™•ํžˆ ํ•œ ๋ฒˆ๋งŒ ํ•ด๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ฐธ์กฐ ํ• ๋‹น์ด ํ•ด์ œ๋  ๋•Œ๊นŒ์ง€ ์†Œ์Šค ์˜์—ญ์ด ๊ณ ์ •๋œ ์ƒํƒœ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ThreadSafeReference๋Š” ์ˆ˜๋ช…์ด ์งง์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

let person = Person(name: "Jane")
let realm = try! Realm()
try! realm.write {
realm.add(person)
}
// Create thread-safe reference to person
let personRef = ThreadSafeReference(to: person)
// Pass the reference to a background thread
DispatchQueue(label: "background", autoreleaseFrequency: .workItem).async {
let realm = try! Realm()
try! realm.write {
// Resolve within the transaction to ensure you get the latest changes from other threads
guard let person = realm.resolve(personRef) else {
return // person was deleted
}
person.name = "Jane Doe"
}
}

๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ๊ฐ์ฒด๋กœ ์ž‘์—…ํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ํ•ด๋‹น ์Šค๋ ˆ๋“œ์—์„œ ๊ฐ์ฒด๋ฅผ ๋‹ค์‹œ ์ฟผ๋ฆฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ์ฒด์— ํ”„๋ผ์ด๋จธ๋ฆฌ ํ‚ค๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ์ด๋ฅผ ์ฟผ๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ํ‚ค๊ฐ€ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๊ด€๊ณ„์—†์ด ๋ชจ๋“  ๊ฐ์ฒด์—์„œ ThreadSafeReference๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชฉ๋ก ๋ฐ ๊ฒฐ๊ณผ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹จ์ ์€ ThreadSafeReference์— ๋ช‡ ๊ฐ€์ง€ ์ƒ์šฉ๊ตฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด๊ฐ€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์— ๋‚จ์•„ ์žˆ์ง€ ์•Š๋„๋ก ์ ์ ˆํ•œ ๋ฒ”์œ„์˜ autoreleaseFrequency๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DispatchQueue์˜ ๋ชจ๋“  ํ•ญ๋ชฉ์„ ๋ž˜ํ•‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์šฉ๊ตฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํŽธ์˜ ํ™•์žฅ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

extension Realm {
func writeAsync<T: ThreadConfined>(_ passedObject: T, errorHandler: @escaping ((_ error: Swift.Error) -> Void) = { _ in return }, block: @escaping ((Realm, T?) -> Void)) {
let objectReference = ThreadSafeReference(to: passedObject)
let configuration = self.configuration
DispatchQueue(label: "background", autoreleaseFrequency: .workItem).async {
do {
let realm = try Realm(configuration: configuration)
try realm.write {
// Resolve within the transaction to ensure you get the latest changes from other threads
let object = realm.resolve(objectReference)
block(realm, object)
}
} catch {
errorHandler(error)
}
}
}
}

์ด ํ™•์žฅ์€ Realm ํด๋ž˜์Šค์— writeAsync() ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์‹œ

์ด๋ฉ”์ผ ์•ฑ์„ ๋งŒ๋“ค์—ˆ๊ณ  ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ฝ์€ ๋ชจ๋“  ์ด๋ฉ”์ผ์„ ์‚ญ์ œํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋‘ ์ค„์˜ ์ฝ”๋“œ๋กœ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋กœ์ €๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋˜๋ฉฐ ์˜์—ญ๊ณผ ์ „๋‹ฌ๋œ ๊ฐ์ฒด ๋ชจ๋‘์˜ ์ž์ฒด ๋ฒ„์ „์„ ์ˆ˜์‹ ํ•œ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•ฉ๋‹ˆ๋‹ค.

let realm = try! Realm()
let readEmails = realm.objects(Email.self).where {
$0.read == true
}
realm.writeAsync(readEmails) { (realm, readEmails) in
guard let readEmails = readEmails else {
// Already deleted
return
}
realm.delete(readEmails)
}

์Šค๋ ˆ๋“œ ๊ฐ„์— ์˜์—ญ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ๋™์ผํ•œ Realm ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๊ฐ ์Šค๋ ˆ๋“œ์—์„œ ๋‹ค๋ฅธ Realm ์ธ์Šคํ„ด์Šค๋ฅผ ์—ฝ๋‹ˆ๋‹ค. ๋™์ผํ•œ ๊ตฌ์„ฑ ์„ ์‚ฌ์šฉํ•˜๋Š” ํ•œ ๋ชจ๋“  Realm ์ธ์Šคํ„ด์Šค๋Š” ๋””์Šคํฌ์˜ ๋™์ผํ•œ ํŒŒ์ผ์— ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค.

์˜์—ญ์„ ์—ด๋ฉด ๊ฐ€์žฅ ์ตœ๊ทผ์— ์„ฑ๊ณตํ•œ ์“ฐ๊ธฐ ์ปค๋ฐ‹์ด ๋ฐ˜์˜๋˜๋ฉฐ ์ƒˆ๋กœ ๊ณ ์นจํ•  ๋•Œ๊นŒ์ง€ ํ•ด๋‹น ๋ฒ„์ „์œผ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์˜์—ญ์ด ๋‹ค์Œ ์ƒˆ๋กœ ๊ณ ์นจ๊นŒ์ง€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ๋ฐœ์ƒํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ณผ ์ˆ˜ ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. UI ์Šค๋ ˆ๋“œ์˜ ์˜์—ญ, ๋” ์ •ํ™•ํ•˜๊ฒŒ๋Š” ์ด๋ฒคํŠธ ๋ฃจํ”„ ์Šค๋ ˆ๋“œ์˜ ์˜์—ญ์€ ํ•ด๋‹น ์Šค๋ ˆ๋“œ์˜ ๋ฃจํ”„๊ฐ€ ์‹œ์ž‘๋  ๋•Œ ์ž๋™์œผ๋กœ ์ƒˆ๋กœ ๊ณ ์ณ์ง‘๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฃจํ”„ ์Šค๋ ˆ๋“œ์— ์กด์žฌํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์ž๋™ ์ƒˆ๋กœ ๊ณ ์นจ์ด ๋น„ํ™œ์„ฑํ™”๋œ ์˜์—ญ ์ธ์Šคํ„ด์Šค๋Š” ์ˆ˜๋™์œผ๋กœ ์ƒˆ๋กœ ๊ณ ์นจํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

if (![realm autorefresh]) {
[realm refresh]
}
if (!realm.autorefresh) {
// Manually refresh
realm.refresh()
}

์Šค๋ ˆ๋“œ์— ์ œํ•œ๋œ ๋ผ์ด๋ธŒ ๊ฐ์ฒด๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ผ๋ถ€ ์•ฑ(์˜ˆ์‹œ: ๋ฐ˜์‘ํ˜• ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆผ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์•ฑ)์€ ์ตœ์ข…์ ์œผ๋กœ UI ์Šค๋ ˆ๋“œ์— ๋„๋‹ฌํ•˜๊ธฐ ์ „์— ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ๋ถˆ๋ณ€์˜ ๋ณต์‚ฌ๋ณธ์„ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋กœ ์ „์†กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋งค๋ฒˆ ๋”ฅ ์นดํ”ผ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ๋น„์šฉ์ด ๋งŽ์ด ๋“ค๊ณ  ์˜์—ญ์€ ๋ผ์ด๋ธŒ ์ธ์Šคํ„ด์Šค๋ฅผ ์Šค๋ ˆ๋“œ ๊ฐ„์— ๊ณต์œ ํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ๊ฐ์ฒด, ์ปฌ๋ ‰์…˜ ๋ฐ ์˜์—ญ์„ ๋™๊ฒฐ ๋ฐ ๋™๊ฒฐ ํ•ด์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋™๊ฒฐํ•˜๋ฉด ํŠน์ • ๊ฐ์ฒด, ์ปฌ๋ ‰์…˜ ๋˜๋Š” ์˜์—ญ์— ๋Œ€ํ•œ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ๋ณด๊ธฐ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๋™๊ฒฐ๋œ ๊ฐ์ฒด, ์ปฌ๋ ‰์…˜ ๋˜๋Š” ์˜์—ญ์€ ์—ฌ์ „ํžˆ ๋””์Šคํฌ์— ์กด์žฌํ•˜๋ฉฐ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋กœ ์ „๋‹ฌ๋  ๋•Œ ๋”ฅ ์นดํ”ผ๊ฐ€ ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๊ฑฑ์ • ์—†์ด ์Šค๋ ˆ๋“œ ๊ฐ„์— ๋™๊ฒฐ๋œ ๊ฐ์ฒด๋ฅผ ์ž์œ ๋กญ๊ฒŒ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜์—ญ์„ ๋™๊ฒฐํ•˜๋ฉด ๊ทธ ํ•˜์œ„ ๊ฐ์ฒด๋„ ๋™๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

ํŒ

Swift Actor์™€ ํ•จ๊ป˜ ThreadSafeReference ์‚ฌ์šฉ

Realm์€ ํ˜„์žฌ ์Šค์œ„ํ”„ํŠธ ํ–‰์œ„์ž์™€ thaw()์„(๋ฅผ) ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ–‰์œ„์ž ๊ฒฝ๊ณ„๋ฅผ ๋„˜์–ด Realm ๋ฐ์ดํ„ฐ๋กœ ์ž‘์—…ํ•˜๋ ค๋ฉด ๋™๊ฒฐ๋œ ๊ฐ์ฒด ๋Œ€์‹  ThreadSafeReference๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ThreadSafeReference ๊ณต์œ ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๋™๊ฒฐ๋œ ๊ฐ์ฒด๋Š” ๋ผ์ด๋ธŒ ์ƒํƒœ๊ฐ€ ์•„๋‹ˆ๋ฉฐ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์‹ค์ƒ ์ •์ง€ ์‹œ์ ์˜ ๊ฐ์ฒด ์ƒํƒœ์— ๋Œ€ํ•œ ์Šค๋ƒ…์ƒท์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด๋ฅผ ๋™๊ฒฐ ํ•ด์ œํ•˜๋ฉด ๋™๊ฒฐ๋œ ๊ฐ์ฒด์˜ ๋ผ์ด๋ธŒ ๋ฒ„์ „์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

// Get an immutable copy of the realm that can be passed across threads
RLMRealm *frozenRealm = [realm freeze];
RLMResults *dogs = [Dog allObjectsInRealm:realm];
// You can freeze collections
RLMResults *frozenDogs = [dogs freeze];
// You can still read from frozen realms
RLMResults *frozenDogs2 = [Dog allObjectsInRealm:frozenRealm];
Dog *dog = [dogs firstObject];
// You can freeze objects
Dog *frozenDog = [dog freeze];
// To modify frozen objects, you can thaw them
// You can thaw collections
RLMResults *thawedDogs = [dogs thaw];
// You can thaw objects
Dog *thawedDog = [dog thaw];
// You can thaw frozen realms
RLMRealm *thawedRealm = [realm thaw];
let realm = try! Realm()
// Get an immutable copy of the realm that can be passed across threads
let frozenRealm = realm.freeze()
assert(frozenRealm.isFrozen)
let people = realm.objects(Person.self)
// You can freeze collections
let frozenPeople = people.freeze()
assert(frozenPeople.isFrozen)
// You can still read from frozen realms
let frozenPeople2 = frozenRealm.objects(Person.self)
assert(frozenPeople2.isFrozen)
let person = people.first!
assert(!person.realm!.isFrozen)
// You can freeze objects
let frozenPerson = person.freeze()
assert(frozenPerson.isFrozen)
// Frozen objects have a reference to a frozen realm
assert(frozenPerson.realm!.isFrozen)

๋™๊ฒฐ๋œ ๊ฐ์ฒด๋กœ ์ž‘์—…ํ•  ๋•Œ ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜๋ฅผ ์‹œ๋„ํ•˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • ๋™๊ฒฐ๋œ ์˜์—ญ์—์„œ ์“ฐ๊ธฐ ํŠธ๋žœ์žญ์…˜(write transaction) ์—ด๊ธฐ

  • ๋™๊ฒฐ๋œ ๊ฐ์ฒด ์ˆ˜์ •

  • ๋™๊ฒฐ๋œ ์˜์—ญ, ์ปฌ๋ ‰์…˜ ๋˜๋Š” ๊ฐ์ฒด์— ๋ณ€๊ฒฝ ๋ฆฌ์Šค๋„ˆ ์ถ”๊ฐ€

isFrozen์„(๋ฅผ) ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๊ฐ€ ๋™๊ฒฐ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ์ด๋Š” ํ•ญ์ƒ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

if ([realm isFrozen]) {
// ...
}
if (realm.isFrozen) {
// ...
}

๋™๊ฒฐ๋œ ๊ฐ์ฒด๋Š” ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ๋ผ์ด๋ธŒ ์˜์—ญ์ด ์—ด๋ ค ์žˆ๋Š” ํ•œ ์œ ํšจํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๋™๊ฒฐ๋œ ๊ฐ์ฒด๋กœ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋ผ์ด๋ธŒ ์˜์—ญ์„ ๋‹ซ์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ ์˜์—ญ์ด ๋‹ซํžˆ๊ธฐ ์ „์— ๋™๊ฒฐ๋œ ์˜์—ญ์„ ๋‹ซ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ค‘์š”

๋™๊ฒฐ๋œ ๊ฐ์ฒด๋ฅผ ์บ์‹ฑํ•˜๋Š” ๊ฒฝ์šฐ

๋™๊ฒฐ๋œ ๊ฐ์ฒด๋ฅผ ๋„ˆ๋ฌด ๋งŽ์ด ์บ์‹ฑํ•˜๋ฉด ์˜์—ญ ํŒŒ์ผ ํฌ๊ธฐ์— ๋ถ€์ •์ ์ธ ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. '๋„ˆ๋ฌด ๋งŽ์Œ'์€ ํŠน์ • ๋Œ€์ƒ ์žฅ์น˜์™€ Realm ๊ฐ์ฒด์˜ ํฌ๊ธฐ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋งŽ์€ ์ˆ˜์˜ ๋ฒ„์ „์„ ์บ์‹œํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ํ•„์š”ํ•œ ๋ฒ„์ „์„ ์˜์—ญ ์™ธ๋ถ€๋กœ ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋™๊ฒฐ๋œ ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๋ฉด ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ๋™๊ฒฐ ํ•ด์ œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋™๊ฒฐ๋˜์ง€ ์•Š์€ ์˜์—ญ์—์„œ ์ฟผ๋ฆฌํ•œ ๋‹ค์Œ ์ˆ˜์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ ๊ฐ์ฒด, ์ปฌ๋ ‰์…˜ ๋˜๋Š” ์˜์—ญ์—์„œ thaw์„(๋ฅผ) ํ˜ธ์ถœํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

๊ฐ์ฒด ๋˜๋Š” ์ปฌ๋ ‰์…˜์„ ๋™๊ฒฐ ํ•ด์ œํ•˜๋ฉด ๊ฐ์ฒด ๋˜๋Š” ์ปฌ๋ ‰์…˜์ด ์ฐธ์กฐํ•˜๋Š” ์˜์—ญ๋„ ๋™๊ฒฐ ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค.

// Read from a frozen realm
let frozenPeople = frozenRealm.objects(Person.self)
// The collection that we pull from the frozen realm is also frozen
assert(frozenPeople.isFrozen)
// Get an individual person from the collection
let frozenPerson = frozenPeople.first!
// To modify the person, you must first thaw it
// You can also thaw collections and realms
let thawedPerson = frozenPerson.thaw()
// Check to make sure this person is valid. An object is
// invalidated when it is deleted from its managing realm,
// or when its managing realm has invalidate() called on it.
assert(thawedPerson?.isInvalidated == false)
// Thawing the person also thaws the frozen realm it references
assert(thawedPerson!.realm!.isFrozen == false)
// Let's make the code easier to follow by naming the thawed realm
let thawedRealm = thawedPerson!.realm!
// Now, you can modify the todo
try! thawedRealm.write {
thawedPerson!.name = "John Michael Kane"
}

๋™๊ฒฐ๋œ ์ปฌ๋ ‰์…˜์— ์ถ”๊ฐ€ํ•  ๋•Œ๋Š” ์ปฌ๋ ‰์…˜๊ณผ ์ถ”๊ฐ€ํ•˜๋ ค๋Š” ๊ฐ์ฒด๋ฅผ ๋ชจ๋‘ ๋™๊ฒฐ ํ•ด์ œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ์—์„œ๋Š” ๋™๊ฒฐ๋œ Realm์— ์žˆ๋Š” ๋‘ ๊ฐ์ฒด๋ฅผ ์ฟผ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฐœ ๊ฐ์ฒด์˜ ๋ชฉ๋ก ์†์„ฑ์ด ์žˆ๋Š” ์‚ฌ๋žŒ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

  • ๊ฐœ ๊ฐ์ฒด

์‚ฌ๋žŒ์˜ ๊ฐœ ๋ชฉ๋ก ์ปฌ๋ ‰์…˜์— ๊ฐœ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „์— ๋‘ ๊ฐ์ฒด๋ฅผ ๋ชจ๋‘ ๋™๊ฒฐ ํ•ด์ œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ๋žŒ ๊ฐ์ฒด๋งŒ ๋™๊ฒฐ ํ•ด์ œํ•˜๊ณ  ๊ฐœ๋Š” ๋™๊ฒฐ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉด Realm์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ ๊ฐ„์— ๊ณ ์ •๋œ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•  ๋•Œ๋„ ๋™์ผํ•œ ๊ทœ์น™์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ๋Š” UI๋ฅผ ์ฐจ๋‹จํ•˜๋Š” ๋Œ€์‹  ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ผ๋ถ€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// Get a copy of frozen objects.
// Here, we're getting them from a frozen realm,
// but you might also be passing them across threads.
let frozenTimmy = frozenRealm.objects(Person.self).where {
$0.name == "Timmy"
}.first!
let frozenLassie = frozenRealm.objects(Dog.self).where {
$0.name == "Lassie"
}.first!
// Confirm the objects are frozen.
assert(frozenTimmy.isFrozen == true)
assert(frozenLassie.isFrozen == true)
// Thaw the frozen objects. You must thaw both the object
// you want to append and the collection you want to append it to.
let thawedTimmy = frozenTimmy.thaw()
let thawedLassie = frozenLassie.thaw()
let realm = try! Realm()
try! realm.write {
thawedTimmy?.dogs.append(thawedLassie!)
}
XCTAssertEqual(thawedTimmy?.dogs.first?.name, "Lassie")

Realm์€ MVCC(Multiversion Concurrency Control) ๋ฅผ ํ†ตํ•ด ์Šค๋ ˆ๋“œ ์ „๋ฐ˜์— ๊ฑธ์ณ ์•ˆ์ „ํ•˜๊ณ  ๋น ๋ฅด๋ฉฐ ์ž ๊ธˆ ์—†๋Š” ๋™์‹œ ์•ก์„ธ์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์•„ํ‚คํ…์ฒ˜.

Git ๊ณผ ๊ฐ™์€ ๋ถ„์‚ฐ๋œ ๋ฒ„์ „ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์— ์ต์ˆ™ํ•œ ๊ฒฝ์šฐ ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋ฏธ MVCC๋ฅผ ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•˜๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Git์˜ ๋‘ ๊ฐ€์ง€ ๊ธฐ๋ณธ ์š”์†Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์ปค๋ฐ‹, ์ฆ‰ ์›์ž์„ฑ ์“ฐ๊ธฐ์ž…๋‹ˆ๋‹ค.

  • ๋ธŒ๋žœ์น˜, ์ฆ‰ ์ปค๋ฐ‹ ๊ธฐ๋ก์˜ ๋‹ค๋ฅธ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Realm์€ ํŠธ๋žœ์žญ์…˜ํ˜•ํƒœ์˜ ์›์ž ๋‹จ์œ„๋กœ ์ปค๋ฐ‹๋œ ์“ฐ๊ธฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ Realm์€ ๋ธŒ๋žœ์น˜์ฒ˜๋Ÿผ ์ฃผ์–ด์ง„ ์‹œ๊ฐ„์— ๋‹ค์–‘ํ•œ ๋ฒ„์ „์˜ ํžˆ์Šคํ† ๋ฆฌ๋ฅผ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํฌํฌ๋ฅผ ํ†ตํ•œ ๋ฐฐํฌ์™€ ๋ถ„์‚ฐ์„ ์ ๊ทน์ ์œผ๋กœ ์ง€์›ํ•˜๋Š” Git๊ณผ ๋‹ฌ๋ฆฌ ์˜์—ญ์—๋Š” ํ•ญ์ƒ ํ•˜๋‚˜์˜ ์ตœ์‹  ๋ฒ„์ „๋งŒ ์žˆ๊ณ  ํ•ญ์ƒ ์ตœ์‹  ๋ฒ„์ „์˜ ํ—ค๋“œ์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์˜์—ญ์€ ์ด์ „ ๋ฒ„์ „์— ์“ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋ฐ์ดํ„ฐ๊ฐ€ ํ•˜๋‚˜์˜ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์ˆ˜๋ ด๋œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

์˜์—ญ์€ B-ํŠธ๋ฆฌ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค. ์ตœ์ƒ์œ„ ๋…ธ๋“œ๋Š” ์˜์—ญ์˜ ๋ฒ„์ „์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ํ•˜์œ„ ๋…ธ๋“œ๋Š” ํ•ด๋‹น ๋ฒ„์ „์˜ ์˜์—ญ์— ์žˆ๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์˜์—ญ์€ Git์ด HEAD ์ปค๋ฐ‹์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ตœ์‹  ๋ฒ„์ „์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Realm์€ ์“ฐ๊ธฐ ์ค‘ ๋ณต์‚ฌ(copy-on-write) ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฉ๋ฆฌ ๋ฅผ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ๋ฐ ๋‚ด๊ตฌ์„ฑ . ๋ณ€๊ฒฝ์„ ์ˆ˜ํ–‰ํ•˜๋ฉด Realm์€ ํŠธ๋ฆฌ์˜ ๊ด€๋ จ ๋ถ€๋ถ„์„ ๋ณต์‚ฌํ•˜์—ฌ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ Realm์€ ๋‘ ๋‹จ๊ณ„๋กœ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค.

  • Realm์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋””์Šคํฌ์— ๊ธฐ๋กํ•˜๊ณ  ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

  • ๊ทธ๋Ÿฐ ๋‹ค์Œ Realm์€ ์ตœ์‹  ๋ฒ„์ „ ํฌ์ธํ„ฐ๊ฐ€ ์ƒˆ๋กœ ์ž‘์„ฑ๋œ ๋ฒ„์ „์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

2๋‹จ๊ณ„ ์ปค๋ฐ‹ ํ”„๋กœ์„ธ์Šค๋Š” ์“ฐ๊ธฐ๊ฐ€ ๋„์ค‘์— ์‹คํŒจํ•˜๋”๋ผ๋„ ํŠธ๋ฆฌ์˜ ๊ด€๋ จ ๋ถ€๋ถ„ ๋ณต์‚ฌ๋ณธ์ด ๋ณ€๊ฒฝ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์›๋ž˜ ๋ฒ„์ „์ด ์–ด๋–ค ์‹์œผ๋กœ๋“  ์†์ƒ๋˜์ง€ ์•Š๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์˜์—ญ์˜ ๋ฃจํŠธ ํฌ์ธํ„ฐ๋Š” ์ƒˆ ๋ฒ„์ „์ด ์œ ํšจํ•˜๋‹ค๋Š” ๊ฒƒ์ด ๋ณด์žฅ๋  ๋•Œ๊นŒ์ง€ ์›๋ณธ ๋ฒ„์ „์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

์˜ˆ์‹œ

๋‹ค์Œ ๋‹ค์ด์–ด๊ทธ๋žจ์€ ์ปค๋ฐ‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

Realm์€ ์“ฐ๊ธฐ๋ฅผ ์œ„ํ•ด ํŠธ๋ฆฌ์˜ ๊ด€๋ จ ๋ถ€๋ถ„์„ ๋ณต์‚ฌํ•œ ๋‹ค์Œ ํฌ์ธํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ์ตœ์‹  ๋ฒ„์ „์„ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค.
ํด๋ฆญํ•˜์—ฌ ํ™•๋Œ€
  1. ์˜์—ญ์€ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜์—ญ์—๋Š” ์ตœ์‹  ๋ฒ„์ „์ธ V1์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  2. ๊ธฐ๋ก ์‹œ Realm์€ V1์„ ๊ธฐ๋ฐ˜์œผ๋กœ V2 ๋ฒ„์ „์„ ์ƒˆ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. Realm์€ ์ˆ˜์ •์„ ์œ„ํ•ด ๊ฐ์ฒด์˜ ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค๊ณ (A 1, C 1) ์ˆ˜์ •๋˜์ง€ ์•Š์€ ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋งํฌ๋Š” ๊ณ„์†ํ•ด์„œ ์›๋ณธ ๋ฒ„์ „(B, D)์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

  3. ์ปค๋ฐ‹์„ ํ™•์ธํ•œ ํ›„ Realm์€ ํฌ์ธํ„ฐ๋ฅผ ์ƒˆ๋กœ์šด ์ตœ์‹  ๋ฒ„์ „์ธ V2๋กœ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ Realm์€ ๋” ์ด์ƒ ํŠธ๋ฆฌ์— ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์€ ์˜ค๋ž˜๋œ ๋…ธ๋“œ๋ฅผ ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.

Realm์€ ๋ฉ”๋ชจ๋ฆฌ ๋งคํ•‘๊ณผ ๊ฐ™์€ ์ œ๋กœ ์นดํ”ผ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์˜์—ญ์—์„œ ๊ฐ’์„ ์ฝ์œผ๋ฉด ๋ณต์‚ฌ๋ณธ์ด ์•„๋‹Œ ์‚ฌ์‹ค์ƒ ์‹ค์ œ ๋””์Šคํฌ ๊ฐ’์„ ๋ณด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋ผ์ด๋ธŒ ๊ฐ์ฒด์˜ ๊ธฐ๋ณธ์ด๋ฉฐ ๋””์Šคํฌ ์“ฐ๊ธฐ๊ฐ€ ๊ฒ€์ฆ๋œ ํ›„ ์˜์—ญ ํ—ค๋“œ ํฌ์ธํ„ฐ๊ฐ€ ์ƒˆ ๋ฒ„์ „์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

  • Realm์€ ๋‹ค์Œ ์„ธ ๊ฐ€์ง€ ๊ทœ์น™์„ ๋”ฐ๋ฅด๋ฉด ๊ฐ„๋‹จํ•˜๊ณ  ์•ˆ์ „ํ•œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์ฝ”๋“œ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

    • ์ฝ๊ธฐ ์œ„ํ•ด ๋ฝ์„ ํ•˜์ง€ ๋งˆ์„ธ์š”.

    • ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์— ์“ฐ๊ฑฐ๋‚˜ Device Sync๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ UI ์Šค๋ ˆ๋“œ์— ์“ฐ๊ธฐ ๋ฐฉ์ง€

    • ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์— ๋ผ์ด๋ธŒ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜์ง€ ๋งˆ์„ธ์š”.

  • ๊ฐ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋”ฐ๋ผ ์Šค๋ ˆ๋“œ ๊ฐ„์— ๊ฐ์ฒด๋ฅผ ๊ณต์œ ํ•˜๋Š” ์ ์ ˆํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์˜์—ญ ์ธ์Šคํ„ด์Šค์˜ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ณด๋ ค๋ฉด '๋ฃจํ”„' ์Šค๋ ˆ๋“œ์— ์กด์žฌํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์ž๋™ ์ƒˆ๋กœ ๊ณ ์นจ์ด ๋น„ํ™œ์„ฑํ™”๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ƒˆ๋กœ ๊ณ ์นจํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฐ˜์‘ํ˜• ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆผ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์•ฑ์˜ ๊ฒฝ์šฐ ๊ฐ์ฒด, ์ปฌ๋ ‰์…˜ ๋ฐ ์˜์—ญ์„ ๋™๊ฒฐํ•˜์—ฌ ์–•์€ ๋ณต์‚ฌ๋ณธ์„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์— ํšจ์œจ์ ์œผ๋กœ ์ „๋‹ฌํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Realm์˜ ๋ฉ€ํ‹ฐ๋ฒ„์ ผ ๋™์‹œ์„ฑ ์ œ์–ด(MVCC) ์•„ํ‚คํ…์ฒ˜๋Š” Git๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Git๊ณผ๋Š” ๋‹ฌ๋ฆฌ Realm์€ ๊ฐ ์˜์—ญ์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ์‹ค์ œ ์ตœ์‹  ๋ฒ„์ „๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Realm์€ ๊ฒฉ๋ฆฌ ๋ฐ ๋‚ด๊ตฌ์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋‘ ๋‹จ๊ณ„๋กœ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค.

Realm Swift SDK ํผ๋ธ”๋ฆญ API์—๋Š” ํฌ๊ฒŒ ์„ธ ๊ฐ€์ง€ ๋ฒ”์ฃผ๋กœ ๋ถ„๋ฅ˜๋˜๋Š” ์œ ํ˜•์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ „์†ก ๊ฐ€๋Šฅ

  • ์ „์†ก ๋ถˆ๊ฐ€๋Šฅ ๋ฐ ์Šค๋ ˆ๋“œ ์ œํ•œ ์—†์Œ

  • ์Šค๋ ˆ๋“œ ์ œํ•œ

์ „์†ก์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ์œ ํ˜•๊ณผ ์Šค๋ ˆ๋“œ ๊ฐ„์— ์Šค๋ ˆ๋“œ๋กœ ์ œํ•œ๋˜์ง€ ์•Š์€ ์œ ํ˜•์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋ฅผ ๋™๊ธฐํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ์— ํ•œ์ •๋œ ์œ ํ˜•์€ ๋™๊ฒฐ๋˜์ง€ ์•Š๋Š” ํ•œ ๊ฒฉ๋ฆฌ ์ปจํ…์ŠคํŠธ์— ํ•œ์ •๋ฉ๋‹ˆ๋‹ค. ๋™๊ธฐํ™”๋ฅผ ์‚ฌ์šฉํ•ด๋„ ์ด๋Ÿฌํ•œ ์ปจํ…์ŠคํŠธ ๊ฐ„์— ์ „๋‹ฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ „์†ก ๊ฐ€๋Šฅ
Non-Sendable
์Šค๋ ˆ๋“œ ์ œํ•œ

AnyBSON

RLMAppConfiguration

AnyRealmCollection

AsyncOpen

RLMFindOneAndModifyOptions

AnyRealmValue

AsyncOpenSubscription

RLMFindOptions

๋ชฉ๋ก

RLM API ํ‚ค ์ธ์ฆ

RLM ๋„คํŠธ์›Œํฌ ์ „์†ก

Map

RLMApp

RLMRequest

MutableSet

RLMAsyncOpenTask

RLMResponse

ํ”„๋กœ์ ์…˜

RLMChangeStream

RLMSyncConfiguration

RLMArray

RLMCompensatingWriteInfo

RLMSyncTimeoutOptions

RLMChangeStream

RLMCredentials

RLMDictionary

RLMDecimal128

RLMDictionaryChange

RLMEmailPasswordAuth

RLMEmbeddedObject

RLM Max ํ‚ค

RLM ๋งํฌ ์˜ค๋ธŒ์ ํŠธ

RLM Min ํ‚ค

RLMObject

RLM Mongo ํด๋ผ์ด์–ธํŠธ

RLM ์†์„ฑ ๋ณ€๊ฒฝ

RLM Mongo ์ปฌ๋ ‰์…˜

RLMRealm

RLM Mongo ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

RLMResults

RLM ๊ฐ์ฒด ID

RLM ์„น์…˜

RLM ๊ฐ์ฒด ์Šคํ‚ค๋งˆ

RLM ์„น์…˜ ๊ฒฐ๊ณผ

RLM ์ง„ํ–‰ ์•Œ๋ฆผ

RLM ์„น์…˜ ๊ฒฐ๊ณผ ๋ณ€๊ฒฝ ์„ธํŠธ

RLM ์ง„ํ–‰ ์•Œ๋ฆผ ํ† ํฐ

RLMSet

RLM ์†์„ฑ

RLM Sync ๊ตฌ๋…

RLMPropertyDescriptor

RLM Sync ์„œ๋ธŒ์Šคํฌ๋ฆฝ์…˜ ์„ธํŠธ

RLM ์ œ๊ณต์ž ํด๋ผ์ด์–ธํŠธ

RealmOptional

RLM ํ‘ธ์‹œ ํด๋ผ์ด์–ธํŠธ

RealmProperty

RLM ์Šคํ‚ค๋งˆ

RLMSortDescriptor

RLM Sync ์˜ค๋ฅ˜ ์•ก์…˜ ํ† ํฐ

RLM Sync ๊ด€๋ฆฌ์ž

RLM Sync ์„ธ์…˜

RLMThreadSafeReference

RLMUpdateResult

RLM ์‚ฌ์šฉ์ž

RLM ์‚ฌ์šฉ์ž API ํ‚ค

RL ์‚ฌ์šฉ์ž ID

RLM ์‚ฌ์šฉ์ž ํ”„๋กœํ•„

ThreadSafe

๋Œ์•„๊ฐ€๊ธฐ

์‚ญ์ œ