Docs Menu
Docs Home
/ /
Atlas Device SDK
/

변경 사항에 대응 - C++ SDK

이 페이지의 내용

  • 객체 변경 리스너 등록
  • 컬렉션 변경 리스너 등록
  • 결과 collection 변경 리스너 등록
  • 변경 사항에 대한 주시 불필요
  • 알림 한도 변경

모든 Realm 객체는 라이브 객체이므로 수정될 때마다 자동으로 업데이트됩니다. Realm은 속성이 변경될 때마다 알림 이벤트를 발생시킵니다. 알림 처리기를 등록하여 이러한 알림 이벤트를 수신하고 UI를 최신 데이터로 업데이트할 수 있습니다.

영역 내의 특정 객체에 대한 알림 핸들러를 등록할 수 있습니다. 영역은 다음 사항을 핸들러에게 알립니다.

  • 객체가 삭제된 경우

  • 객체의 속성이 변경된 경우

auto token = object.observe([&](auto&& change) { ... }

핸들러는 객체 삭제 여부와 같은 변경 사항에 대한 정보가 포함된 object_change 객체 를 수신합니다. 여기에는 변경된 필드, 해당 필드의 새 값(List 속성 제외), 잠재적으로 필드의 이전 값에 대한 정보가 포함된 PropertyChange 객체 목록이 포함될 수 있습니다.

if (change.error) {
rethrow_exception(change.error);
}
if (change.is_deleted) {
std::cout << "The object was deleted.\n";
} else {
for (auto& propertyChange : change.property_changes) {
std::cout << "The object's " << propertyChange.name
<< " property has changed.\n";
auto newPropertyValue =
std::get<std::string>(*propertyChange.new_value);
std::cout << "The new value is " << newPropertyValue << "\n";
}
}

변경을 수행할 때 영역을 refresh() 하여 알림을 보냅니다.

auto config = realm::db_config();
auto realm = realm::db(std::move(config));
// Create an object and move it into the database.
auto dog = realm::Dog{.name = "Max"};
realm.write([&] { realm.add(std::move(dog)); });
auto dogs = realm.objects<realm::Dog>();
auto specificDog = dogs[0];
// Set up the listener & observe object notifications.
auto token = specificDog.observe([&](auto&& change) {
try {
if (change.error) {
rethrow_exception(change.error);
}
if (change.is_deleted) {
std::cout << "The object was deleted.\n";
} else {
for (auto& propertyChange : change.property_changes) {
std::cout << "The object's " << propertyChange.name
<< " property has changed.\n";
auto newPropertyValue =
std::get<std::string>(*propertyChange.new_value);
std::cout << "The new value is " << newPropertyValue << "\n";
}
}
} catch (std::exception const& e) {
std::cerr << "Error: " << e.what() << "\n";
}
});
// Update the dog's name to see the effect.
realm.write([&] { specificDog.name = "Wolfie"; });
// Deleting the object triggers a delete notification.
realm.write([&] { realm.remove(specificDog); });
// Refresh the database after the change to trigger the notification.
realm.refresh();
// Unregister the token when done observing.
token.unregister();

collection에 알림 핸들러를 등록할 수 있습니다. collection은 기본형 또는 기타 객체를 포함하여 지원되는 모든 데이터 유형 을 포함할 수 있는 목록, 지도 또는 속성입니다.

Realm은 쓰기 트랜잭션(write transaction)이 collection에서 객체를 제거, 추가 또는 변경할 때마다 핸들러에 알립니다.

알림은 제거, 삽입 및 수정된 객체의 인덱스라는 세 가지 인덱스 목록을 사용하여 이전 알림 이후의 변경 사항을 설명합니다.

중요

알림 순서의 중요성

컬렉션 알림 핸들러에서는 항상 삭제, 삽입, 수정의 순서로 변경 사항을 적용합니다. 삭제하기 전에 삽입을 처리하면 예기치 않은 동작이 발생할 수 있습니다.

컬렉션 알림 은 제거, 추가 또는 수정된 객체의 인덱스 를 보고하는 collection_change 구조체를 제공합니다. 컬렉션 이 삭제된 경우에도 알림을 받을 수 있습니다.

이 예제에서 Person 객체에는 Dog 객체 목록이 속성으로 있습니다.

struct Person {
std::string name;
std::vector<Dog*> dogs;
};
REALM_SCHEMA(Person, name, dogs)

개를 제거하거나, 새 개를 추가하거나, 수정하면 알림 핸들러가 Atlas Triggers됩니다.

// Set up the listener & observe a collection.
auto token = person.dogs.observe([&](auto&& changes) {
if (changes.collection_root_was_deleted) {
std::cout << "The collection was deleted.\n";
} else {
// Handle deletions, then insertions, then modifications.
for (auto& collectionChange : changes.deletions) {
std::cout << "The object at index " << std::to_string(collectionChange)
<< " was removed\n";
}
for (auto& collectionChange : changes.insertions) {
std::cout << "The object at index " << std::to_string(collectionChange)
<< " was inserted\n";
}
for (auto& collectionChange : changes.modifications) {
std::cout << "The object at index " << std::to_string(collectionChange)
<< " was modified\n";
}
}
});
// Remove an object from the collection, and then add an object to see
// deletions and insertions.
realm.write([&] {
person.dogs.clear();
person.dogs.push_back(&dog2);
});
// Modify an object to see a modification.
realm.write([&] { dog2.age = 2; });
// Refresh the realm after the change to trigger the notification.
realm.refresh();
// Unregister the token when done observing.
token.unregister();

결과 컬렉션 에 알림 핸들러를 등록할 수 있습니다.

Realm은 쓰기 트랜잭션(write transaction)이 collection에서 객체를 제거, 추가 또는 변경할 때마다 핸들러에 알립니다.

알림은 삭제, 삽입 및 수정된 객체의 인덱스라는 세 가지 인덱스 목록을 사용하여 이전 알림 이후의 변경 사항을 설명합니다.

중요

알림 순서의 중요성

컬렉션 알림 핸들러에서는 항상 삭제, 삽입, 수정의 순서로 변경 사항을 적용합니다. 삭제하기 전에 삽입을 처리하면 예기치 않은 동작이 발생할 수 있습니다.

결과 컬렉션 알림은 삭제, 추가 또는 수정된 객체의 인덱스를 보고하는 results_change 구조체를 제공합니다. 컬렉션이 삭제된 경우에도 알림을 받을 수 있습니다.

// Get a results collection to observe
auto dogs = realm.objects<realm::Dog>();
// Set up the listener & observe results notifications.
auto token = dogs.observe([&](auto&& changes) {
try {
if (changes.collection_root_was_deleted) {
std::cout << "The collection was deleted.\n";
} else {
// Handle deletions, then insertions, then modifications.
for (auto& resultsChange : changes.deletions) {
std::cout << "The object at index " << std::to_string(resultsChange)
<< " was deleted\n";
}
for (auto& resultsChange : changes.insertions) {
std::cout << "The object at index " << std::to_string(resultsChange)
<< " was inserted\n";
}
for (auto& resultsChange : changes.modifications) {
std::cout << "The object at index " << std::to_string(resultsChange)
<< " was modified\n";
}
}
} catch (std::exception const& e) {
std::cerr << "Error: " << e.what() << "\n";
}
});
// Delete and then add an object to see deletions and insertions.
realm.write([&] {
realm.remove(firstDog);
realm.add(std::move(dog2));
});
// Modify an object to see a modification.
realm.write([&] { dog2.age = 2; });
// Refresh the database after the change to trigger the notification.
realm.refresh();
// Unregister the token when done observing.
token.unregister();

observe 호출에서 반환된 토큰이 유효하지 않게 되면 관찰이 중지됩니다. 토큰의 unregister() 멤버 함수를 호출하여 토큰을 명시적으로 무효화할 수 있습니다.

// Unregister the token when done observing.
token.unregister();

중요

원하는 관찰 기간 만큼 토큰 유지

토큰의 소멸자가 호출되면 알림이 중지됩니다. 예를 들어 토큰이 범위를 벗어난 로컬 변수에 있는 경우입니다. std::move 를 사용하여 토큰을 다른 범위의 변수로 전송할 수 있습니다.

중첩된 문서의 변경 내용이 4단계 아래로 내려가면 변경 알림이 트리거되지 않습니다.

5단계 아래 또는 그 이상의 변경 사항을 수신해야 하는 데이터 구조가 있는 경우 해결 방법은 다음과 같습니다.

  • 스키마를 리팩터링하여 중첩을 줄입니다.

  • 사용자가 수동으로 데이터를 새로 고칠 수 있도록 '푸시하여 새로 고침'과 같은 내용을 추가합니다.

돌아가기

스레딩