BlackBerry Spark Communications Services for iOS  1.9.0
ObservableTracker Class Reference
Inheritance diagram for ObservableTracker:

Class Methods

(void) + getterCalledForObject:propertyName:
(void) + setTrackingDisable:

Method Documentation

◆ getterCalledForObject:propertyName:()

+ (void) getterCalledForObject: (id)  targetObject
propertyName: (NSString *)  propertyName 

Adding this in a getter method will allow an instance of ObservableMonitor to trigger if the value changes. KVO is used by ObservableMonitor to track changes.

ObservableTracker will only track the property if it is accessed on the applications main thread. Observable properties may be accessed from any thread, but the [[BBMEnterpriseService shared] readWriteLock] must be locked first to ensure the model does not change during the read. This applies to any property getter than calls getterCalledForObject. Failure to acquire the lock will raise an ObservableTracker Misuse exception.
If an ObservableMonitor is used to track changes to properties on an object with a strong reference to the ObservableMonitor instance, a retain cycle will result. This can be prevented by avoiding this scenario or by setting the reference to the monitor to nil.
//Object A
- (NSString *) getIdentifier
//If this getter method is called inside the block of an ObservableMonitor instance,
//it will trigger the monitor every time the value for identifier changes.
[ObservableTracker getterCalledForObject:self propertyName:@"identifier"];
return _identifier;
//Object B
- (void)monitorIdentifer
//Use a strong reference here so the monitor does not go out of scope and get deallocated
//Any references to self, where self has a strong reference to the monitor must be weak
//inside the monitor block to avoid retain cycles
ThisClass *__weak weakSelf = self;
self.identifierMonitor = [ObservableMonitor monitorActivatedWithName:@"identifierMonitor" block:^{
NSString *identifier = [objectA getIdentifier];
//All changes to objectA will now trigger this block to run
//Do something with "identifier"
//Do some things in the background
dispatch_async(dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Get the readWrite lock if we want to access any monitored properties
[[[BBMEnterpriseService shared] readWriteLock] lock];
//We are not on the main thread. Accessing a monitor-able property here will no longer
//cause the monitor to get triggered
NSString *propVal = [someBBMModelObject getProperty];
//Release the lock when we are done reading observable properties
[[[BBMEnterpriseService shared] readWriteLock] unlock];
dispatch_async(dispatch_get_main_queue(), ^{
//Do some work with propVal on the main thread. Any properties read within this
//block are no longer tracked.
NSString *untrackedProperty = [someBBMModelObject getAnotherProperty];
[someUIElement doTaskThatRequiresMainThread:propVal with:untrackedProperty];
targetObjectThe object to which the property belongs to. This is usually self.
propertyNameThe name of the property to track.

◆ setTrackingDisable:()

+ (void) setTrackingDisable: (BOOL)  disable

This is only meant to be called inside a block run by an instance of ObservableMonitor. When tracking is disabled any changes that would usually trigger a monitor will be ignored. It's very important to enable tracking again in the same block where it was disabled.

This method is not thread-safe. It will raise an ObservableTracker Misuse exception if called from a background thread.
self.contactsMonitor = [ObservableMonitor monitorActivatedWithName:@"contactsMonitor" block:^{
[ObservableTracker setTrackingDisable:YES];
//Do something that would usually trigger the monitor but we want to ignore
[ObservableTracker setTrackingDisable:NO];
//Do something else that would trigger the monitor.
disableSet to YES to disable tracking.