Skip to content

Commit

Permalink
Add ObserverContext to KVO handlers
Browse files Browse the repository at this point in the history
Apple recommends using an address of a static variable as a context pointer to filter out unrelated observer callbacks. If the context is unrelated then the callback should be passed on to the super class.

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOBasics.html
  • Loading branch information
Eitot committed May 13, 2023
1 parent 7ef2500 commit 35df7fa
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 23 deletions.
18 changes: 15 additions & 3 deletions Vienna/Sources/Application/AppController.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@

#define VNA_LOG os_log_create("--", "AppController")

static void *VNAAppControllerObserverContext = &VNAAppControllerObserverContext;

@interface AppController () <InfoPanelControllerDelegate, ActivityPanelControllerDelegate, NSMenuItemValidation, NSToolbarItemValidation>

-(void)installScriptsFolderWatcher;
Expand Down Expand Up @@ -295,7 +297,7 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNot
[self.pluginManager addObserver:self
forKeyPath:NSStringFromSelector(@selector(numberOfPlugins))
options:0
context:nil];
context:VNAAppControllerObserverContext];

// Load the styles into the main menu.
[self populateStyleMenu];
Expand Down Expand Up @@ -1223,7 +1225,16 @@ - (void)populatePluginsMenu {
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
context:(void *)context {
context:(void *)context
{
if (context != VNAAppControllerObserverContext) {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
return;
}

if ([keyPath isEqualToString:NSStringFromSelector(@selector(numberOfPlugins))]) {
NSMenu *menu = ((ViennaApp *)NSApp).articleMenu;

Expand Down Expand Up @@ -3571,7 +3582,8 @@ - (FoldersTree *)foldersTree {
-(void)dealloc
{
[self.pluginManager removeObserver:self
forKeyPath:NSStringFromSelector(@selector(numberOfPlugins))];
forKeyPath:NSStringFromSelector(@selector(numberOfPlugins))
context:VNAAppControllerObserverContext];

[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Expand Down
18 changes: 15 additions & 3 deletions Vienna/Sources/Main window/ArticleController.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@

#define VNA_LOG os_log_create("--", "ArticleController")

static void *VNAArticleControllerObserverContext = &VNAArticleControllerObserverContext;

@interface ArticleController ()

-(NSArray *)applyFilter:(NSArray *)unfilteredArray;
Expand Down Expand Up @@ -131,7 +133,7 @@ -(instancetype)init
[NSUserDefaults.standardUserDefaults addObserver:self
forKeyPath:MAPref_FilterMode
options:0
context:nil];
context:VNAArticleControllerObserverContext];

queue = dispatch_queue_create("uk.co.opencommunity.vienna2.displayRefresh", DISPATCH_QUEUE_SERIAL);
requireSelectArticleAfterReload = NO;
Expand Down Expand Up @@ -1146,7 +1148,16 @@ - (BOOL)filterArticle:(Article *)article usingMode:(NSInteger)filterMode {
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
context:(void *)context {
context:(void *)context
{
if (context != VNAArticleControllerObserverContext) {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
return;
}

if ([keyPath isEqualToString:MAPref_FilterMode]) {
// Update the list of articles when the user changes the filter.
@synchronized(mainArticleView) {
Expand All @@ -1158,7 +1169,8 @@ - (void)observeValueForKeyPath:(NSString *)keyPath
- (void)dealloc {
[NSNotificationCenter.defaultCenter removeObserver:self];
[NSUserDefaults.standardUserDefaults removeObserver:self
forKeyPath:MAPref_FilterMode];
forKeyPath:MAPref_FilterMode
context:VNAArticleControllerObserverContext];
}

@end
12 changes: 6 additions & 6 deletions Vienna/Sources/Main window/ArticleListView.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
// Shared defaults key
NSString * const MAPref_ShowEnclosureBar = @"ShowEnclosureBar";

static void *ObserverContext = &ObserverContext;
static void *VNAArticleListViewObserverContext = &VNAArticleListViewObserverContext;

@interface ArticleListView ()

Expand Down Expand Up @@ -182,11 +182,11 @@ -(void)initialiseArticleView
[userDefaults addObserver:self
forKeyPath:MAPref_ShowEnclosureBar
options:NSKeyValueObservingOptionNew
context:ObserverContext];
context:VNAArticleListViewObserverContext];
[userDefaults addObserver:self
forKeyPath:MAPref_ShowUnreadArticlesInBold
options:0
context:ObserverContext];
context:VNAArticleListViewObserverContext];
}

/* initTableView
Expand Down Expand Up @@ -1651,10 +1651,10 @@ -(void)dealloc
NSUserDefaults *userDefaults = NSUserDefaults.standardUserDefaults;
[userDefaults removeObserver:self
forKeyPath:MAPref_ShowEnclosureBar
context:ObserverContext];
context:VNAArticleListViewObserverContext];
[userDefaults removeObserver:self
forKeyPath:MAPref_ShowUnreadArticlesInBold
context:ObserverContext];
context:VNAArticleListViewObserverContext];
[splitView2 setDelegate:nil];
[articleList setDelegate:nil];
}
Expand All @@ -1666,7 +1666,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
context:(void *)context
{
if (context != ObserverContext) {
if (context != VNAArticleListViewObserverContext) {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
Expand Down
2 changes: 0 additions & 2 deletions Vienna/Sources/Main window/FolderView.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
VNAFeedListRowHeight const VNAFeedListRowHeightSmall = 24.0;
VNAFeedListRowHeight const VNAFeedListRowHeightMedium = 28.0;

static void *ObserverContext = &ObserverContext;

@interface FolderView ()

@property (weak, nonatomic) IBOutlet NSView *floatingResetButtonView;
Expand Down
12 changes: 6 additions & 6 deletions Vienna/Sources/Main window/FoldersTree.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
NSString * const MAPref_FeedListSizeMode = @"FeedListSizeMode";
NSString * const MAPref_ShowFeedsWithUnreadItemsInBold = @"ShowFeedsWithUnreadItemsInBold";

static void *ObserverContext = &ObserverContext;
static void *VNAFoldersTreeObserverContext = &VNAFoldersTreeObserverContext;

@interface FoldersTree ()

Expand Down Expand Up @@ -122,11 +122,11 @@ -(void)initialiseFoldersTree
[userDefaults addObserver:self
forKeyPath:MAPref_FeedListSizeMode
options:0
context:ObserverContext];
context:VNAFoldersTreeObserverContext];
[userDefaults addObserver:self
forKeyPath:MAPref_ShowFeedsWithUnreadItemsInBold
options:0
context:ObserverContext];
context:VNAFoldersTreeObserverContext];
}

- (void)dealloc
Expand All @@ -136,10 +136,10 @@ - (void)dealloc
NSUserDefaults *userDefaults;
[userDefaults removeObserver:self
forKeyPath:MAPref_FeedListSizeMode
context:ObserverContext];
context:VNAFoldersTreeObserverContext];
[userDefaults removeObserver:self
forKeyPath:MAPref_ShowFeedsWithUnreadItemsInBold
context:ObserverContext];
context:VNAFoldersTreeObserverContext];
}

-(void)handleOpenReaderFolderChange:(NSNotification *)nc
Expand Down Expand Up @@ -1105,7 +1105,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
context:(void *)context
{
if (context != ObserverContext) {
if (context != VNAFoldersTreeObserverContext) {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
Expand Down
18 changes: 15 additions & 3 deletions Vienna/Sources/Main window/UnifiedDisplayView.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#define YPOS_IN_CELL 2.0
#define PROGRESS_INDICATOR_DIMENSION 16

static void *VNAUnifiedDisplayViewObserverContext = &VNAUnifiedDisplayViewObserverContext;

@interface UnifiedDisplayView () <CustomWKHoverUIDelegate>

@property (nonatomic) OverlayStatusBar *statusBar;
Expand Down Expand Up @@ -144,7 +146,7 @@ -(void)initTableView
[NSUserDefaults.standardUserDefaults addObserver:self
forKeyPath:MAPref_ShowStatusBar
options:NSKeyValueObservingOptionInitial
context:nil];
context:VNAUnifiedDisplayViewObserverContext];
}

/* dealloc
Expand All @@ -153,7 +155,8 @@ -(void)initTableView
-(void)dealloc
{
[NSUserDefaults.standardUserDefaults removeObserver:self
forKeyPath:MAPref_ShowStatusBar];
forKeyPath:MAPref_ShowStatusBar
context:VNAUnifiedDisplayViewObserverContext];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[articleList setDataSource:nil];
[articleList setDelegate:nil];
Expand Down Expand Up @@ -813,7 +816,16 @@ -(void)keyDown:(NSEvent *)theEvent
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
context:(void *)context {
context:(void *)context
{
if (context != VNAUnifiedDisplayViewObserverContext) {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
return;
}

if ([keyPath isEqualToString:MAPref_ShowStatusBar]) {
BOOL isStatusBarShown = [Preferences standardPreferences].showStatusBar;
if (isStatusBarShown && !self.statusBar) {
Expand Down

0 comments on commit 35df7fa

Please sign in to comment.