aboutsummaryrefslogtreecommitdiff
path: root/Foundation
diff options
context:
space:
mode:
authorGravatar Thomas Van Lenten <thomasvl@google.com>2016-08-05 13:58:05 -0400
committerGravatar Thomas Van Lenten <thomasvl@google.com>2016-08-05 13:58:05 -0400
commitecdb1b2b710e30315c1d77ccbea961db64287c00 (patch)
tree7743f15f96a94e879fdb071f01161279f8bec35f /Foundation
parent5b9fc43f5bc840ea1badd96744f9dae50ce039b1 (diff)
Make GTMLogLevelFilter use KVO on GTMVerboseLogging in sharedUserDefaults
This avoids checking if verbose logging is enabled on every user defaults change, and only does so when the verbose logging key changes. In sampling a few apps, this showed up as a hit when the app changes default (directly or via the System frameworks storing things). By using KVO for it it basically disappears from the samples.
Diffstat (limited to 'Foundation')
-rw-r--r--Foundation/GTMLogger.h1
-rw-r--r--Foundation/GTMLogger.m45
2 files changed, 30 insertions, 16 deletions
diff --git a/Foundation/GTMLogger.h b/Foundation/GTMLogger.h
index a776922..16f0eaf 100644
--- a/Foundation/GTMLogger.h
+++ b/Foundation/GTMLogger.h
@@ -457,6 +457,7 @@ typedef enum {
@interface GTMLogLevelFilter : NSObject <GTMLogFilter> {
@private
BOOL verboseLoggingEnabled_;
+ NSUserDefaults *userDefaults_;
}
@end // GTMLogLevelFilter
diff --git a/Foundation/GTMLogger.m b/Foundation/GTMLogger.m
index 7c2a543..3ace20f 100644
--- a/Foundation/GTMLogger.m
+++ b/Foundation/GTMLogger.m
@@ -97,7 +97,7 @@ static GTMLogger *gSharedLogger = nil;
// Don't trust NSFileHandle not to throw
@try {
- GTMLogBasicFormatter *formatter = [[[GTMLogBasicFormatter alloc] init]
+ GTMLogBasicFormatter *formatter = [[[GTMLogBasicFormatter alloc] init]
autorelease];
GTMLogger *stdoutLogger =
[self loggerWithWriter:[NSFileHandle fileHandleWithStandardOutput]
@@ -475,12 +475,13 @@ static GTMLogger *gSharedLogger = nil;
@end // GTMLogStandardFormatter
+static NSString *const kVerboseLoggingKey = @"GTMVerboseLogging";
+
// Check the environment and the user preferences for the GTMVerboseLogging key
// to see if verbose logging has been enabled. The environment variable will
// override the defaults setting, so check the environment first.
// COV_NF_START
-static BOOL IsVerboseLoggingEnabled(void) {
- static NSString *const kVerboseLoggingKey = @"GTMVerboseLogging";
+static BOOL IsVerboseLoggingEnabled(NSUserDefaults *userDefaults) {
NSString *value = [[[NSProcessInfo processInfo] environment]
objectForKey:kVerboseLoggingKey];
if (value) {
@@ -495,7 +496,7 @@ static BOOL IsVerboseLoggingEnabled(void) {
return NO;
}
}
- return [[NSUserDefaults standardUserDefaults] boolForKey:kVerboseLoggingKey];
+ return [userDefaults boolForKey:kVerboseLoggingKey];
}
// COV_NF_END
@@ -504,21 +505,28 @@ static BOOL IsVerboseLoggingEnabled(void) {
- (id)init {
self = [super init];
if (self) {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(defaultsChanged:)
- name:NSUserDefaultsDidChangeNotification
- object:nil];
-
- verboseLoggingEnabled_ = IsVerboseLoggingEnabled();
+ // Keep a reference to standardUserDefaults, avoiding a crash if client code calls
+ // "NSUserDefaults resetStandardUserDefaults" which releases it from memory. We are still
+ // notified of changes through our instance. Note: resetStandardUserDefaults does not actually
+ // clear settings:
+ // https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/index.html#//apple_ref/occ/clm/NSUserDefaults/resetStandardUserDefaults
+ // and so should only be called in test code if necessary.
+ userDefaults_ = [[NSUserDefaults standardUserDefaults] retain];
+ [userDefaults_ addObserver:self
+ forKeyPath:kVerboseLoggingKey
+ options:NSKeyValueObservingOptionNew
+ context:nil];
+
+ verboseLoggingEnabled_ = IsVerboseLoggingEnabled(userDefaults_);
}
return self;
}
- (void)dealloc {
- [[NSNotificationCenter defaultCenter] removeObserver:self
- name:NSUserDefaultsDidChangeNotification
- object:nil];
+ [userDefaults_ removeObserver:self forKeyPath:kVerboseLoggingKey];
+ [userDefaults_ release];
+
[super dealloc];
}
@@ -552,8 +560,14 @@ static BOOL IsVerboseLoggingEnabled(void) {
return allow;
}
-- (void)defaultsChanged:(NSNotification *)note {
- verboseLoggingEnabled_ = IsVerboseLoggingEnabled();
+- (void)observeValueForKeyPath:(NSString *)keyPath
+ ofObject:(id)object
+ change:(NSDictionary *)change
+ context:(void *)context
+{
+ if([keyPath isEqual:kVerboseLoggingKey]) {
+ verboseLoggingEnabled_ = IsVerboseLoggingEnabled(userDefaults_);
+ }
}
@end // GTMLogLevelFilter
@@ -632,4 +646,3 @@ static BOOL IsVerboseLoggingEnabled(void) {
// See comment at top of file.
#pragma GCC diagnostic error "-Wmissing-format-attribute"
#endif // !__clang__
-