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

Instance Methods

(id) - initWithName:block:
 
(id) - initWithName:selfTerminatingBlock:
 
(void) - activate
 
(void) - deActivate
 

Class Methods

(ObservableMonitor *) + monitorActivatedWithName:block:
 
(ObservableMonitor *) + monitorActivatedWithName:selfTerminatingBlock:
 

Properties

BOOL limitFrequency
 

Detailed Description

An instance of this class will execute a given block and track any calls to getterCalledForObject:propertyName in ObservableTracker. The ObservableMonitor will automatically add and remove KVO observers for any properties who's getter calls getterCalledForObject:property and re-run the supplied block each time any of those properties changes.

Since
R3

Method Documentation

◆ activate()

- (void) activate

Activates the monitor. Monitors created with "monitorActivatedWithName" will be automatically activated and executed synchronously.

Warning
Observable monitors are not thread-safe. They should always be activated on the application's main thread.
Since
R3

◆ deActivate()

- (void) deActivate

Deactivates the monitor.

Warning
Observable monitors are not thread-safe. They should always be deactivated on the application's main thread.
Since
R3

◆ initWithName:block:()

- (id) initWithName: (NSString *)  name
block: (void(^)(void))  executionBlock 

Creates a new monitor with the given name and executionBlock. Similar to monitorActivatedWithName:block: except the monitor is not activated immediately.

Parameters
nameThe name of the monitor. This is only used for debugging purposes.
executionBlockThe block of code to execute and monitor for observables.
Since
R3

◆ initWithName:selfTerminatingBlock:()

- (id) initWithName: (NSString *)  name
selfTerminatingBlock: (BOOL(^)(void))  executionBlock 

Creates a new self-terminating monitor with the given name and executionBlock. The execution block should return YES to stop execution of the monitor. Similar to monitorActivatedWithName:selfTerminatingBlock: except the monitor is not activated immediately.

Parameters
nameThe name of the monitor. This is only used for debugging purposes.
executionBlockThe block of code to execute and monitor for observables.
Since
R3

◆ monitorActivatedWithName:block:()

+ (ObservableMonitor*) monitorActivatedWithName: (NSString *)  name
block: (void(^)(void))  executeBlock 

Creates a monitor, activates and runs it immediately. The supplied executeBlock will be run each time any of the referenced observable properties inside the block changes.

- (void)monitorSomeProperties
{
//Use a strong reference so the monitor does not go out of scope and get immediately deallocated
//You may also use an ObservableMonitorSet which will keep strong references to a monitor as
//long as it remains active
//Any references to self, where self has a strong reference to the monitor must be weak
//inside the monitor block to avoid retain cycles
__typeof__(self) __weak weakSelf = self;
self.identifierMonitor = [ObservableMonitor monitorActivatedWithName:@"identifierMonitor" block:^{
NSString *propVal = weakSelf.someBBMModelObject.interestingProperty;
//All changes to someBBMModelObject.interestingProperty will now trigger this block to run
//Any observable properties that are referenced inside of "doInterestingThings" will also
//cause this block to run when they are changed.
[weakSelf.someObject doInterestingThings];
//Do some work
//We want to look at another property or call a method that references monitored properties
//but we don't want changes to those properties trigger this monitor block
[ObservableTracker setTrackingDisabled:YES];
NSString *anotherProp = someBBMModelObject.otherProperty;
[weakSelf.someObject doOtherInterestingThings];
[ObservableTracker setTrackingDisabled:NO];
//Do some things in the background
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Get the readWrite lock if we want to access any monitored properties off the main thread
//This will ensure incoming changes do not update the model while you are reading from it
[[[BBMEnterpriseService shared] readWriteLock] lock];
//We are not on the main thread so accessing a monitor-able property here will no longer
//cause the monitor to get triggered
NSString *propVal = someBBMModelObject.another.interestingProperty;
//Release the lock when we are done reading observable properties
[[[BBMEnterpriseService shared] readWriteLock] unlock];
dispatch_async(dispatch_get_main_queue(), ^{
//Do some work back on the main queue. Properties read here are no longer tracked.
//Acquiring the lock is not required as we're now on the main thread.
});
});
}];
}
Warning
Observable monitors are not thread-safe. They should always be activated on the application's main thread. Observable properties accessed off the application's main thread will not trigger the monitor to run as the ObservableTracker will not track unless [NSThread isMainThread] == YES
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.
Parameters
nameThe name of the monitor. This is only used for debugging purposes.
executeBlockThe block that will be executed each time the monitor runs. This will always be executed on the applications main thread.
Returns
ObservableMonitor The monitor that was created.
Since
R3

◆ monitorActivatedWithName:selfTerminatingBlock:()

+ (ObservableMonitor*) monitorActivatedWithName: (NSString *)  name
selfTerminatingBlock: (BOOL(^)(void))  executeBlock 

Creates a monitor, activates and runs it immediately. The supplied executeBlock will be run each time any of the referenced observable properties inside the block changes. If the block return YES the monitor will be terminated. If the block returns NO it will continue to be active until it returns YES.

If you cannot, or do not want to maintain a strong reference to a self-terminating block, you may use an ObservableMonitorSet, which will keep references to ObservableMonitors until they terminate.

- (void)monitorSomeProperties
{
//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"
selfTerminatingBlock:^(BOOL){
NSString *propVal = someBBMModelObject.interestingProperty;
//All changes to someBBMModelObject.interestingProperty will now trigger this block to run
//Do something with "propVal"
if(![propVal isEqualToString:kTheValueWeWant]) {
//Exit the monitoractivated
return NO;
}
//Property is now the value we wanted
//Do what we need to do
return YES;
//The monitor will now be deactivated
}];
}
Warning
Observable monitors are not thread-safe. They should always be activated on the application's main thread. Observable properties accessed off the application's main thread will not trigger the monitor to run as the ObservableTracker will not track unless [NSThread isMainThread] == YES
An ObservableMonitor cannot be used to track changes to properties on an object with a strong reference to the ObservableMonitor instance. This will result in a retain cycle.
See also
ObservableMonitorSet
Parameters
nameThe name of the monitor. This is only used for debugging purposes.
executeBlockThe block that will be executed each time the monitor runs. The monitor will run until this block returns YES. This block will always execute on the application's main thread.
Returns
ObservableMonitor The monitor that was created.
Since
R3

Property Documentation

◆ limitFrequency

- (BOOL) limitFrequency
readwriteatomicassign

When set, the monitor will wait for 3 seconds between runs. This should be turned on when a monitor will be triggered often enough that the main thread could be blocked.

Since
R3