Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Unified Diff: base/ios/crb_protocol_observers.mm

Issue 935333002: Update from https://crrev.com/316786 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/ios/crb_protocol_observers.h ('k') | base/ios/crb_protocol_observers_unittest.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/ios/crb_protocol_observers.mm
diff --git a/base/ios/crb_protocol_observers.mm b/base/ios/crb_protocol_observers.mm
new file mode 100644
index 0000000000000000000000000000000000000000..ee9e23fcb4e255c29ff0a33590027a25360d9d0e
--- /dev/null
+++ b/base/ios/crb_protocol_observers.mm
@@ -0,0 +1,99 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "base/ios/crb_protocol_observers.h"
+
+#include <objc/runtime.h>
+
+#include "base/logging.h"
+#include "base/mac/scoped_nsobject.h"
+
+@interface CRBProtocolObservers ()
+
+// Designated initializer.
+- (id)initWithProtocol:(Protocol*)protocol;
+
+@end
+
+@implementation CRBProtocolObservers {
+ base::scoped_nsobject<Protocol> _protocol;
+ base::scoped_nsobject<NSHashTable> _observers;
+}
+
++ (CRBProtocolObservers*)observersWithProtocol:(Protocol*)protocol {
+ return [[[self alloc] initWithProtocol:protocol] autorelease];
+}
+
+- (id)init {
+ NOTREACHED();
+ return nil;
+}
+
+- (id)initWithProtocol:(Protocol*)protocol {
+ self = [super init];
+ if (self) {
+ _protocol.reset([protocol retain]);
+ _observers.reset([[NSHashTable weakObjectsHashTable] retain]);
+ }
+ return self;
+}
+
+- (Protocol*)protocol {
+ return _protocol.get();
+}
+
+- (void)addObserver:(id)observer {
+ DCHECK([observer conformsToProtocol:self.protocol]);
+ [_observers addObject:observer];
+}
+
+- (void)removeObserver:(id)observer {
+ [_observers removeObject:observer];
+}
+
+#pragma mark - NSObject
+
+- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector {
+ NSMethodSignature* signature = [super methodSignatureForSelector:selector];
+ if (signature)
+ return signature;
+
+ // Look for a required method in the protocol. protocol_getMethodDescription
+ // returns a struct whose fields are null if a method for the selector was
+ // not found.
+ struct objc_method_description description =
+ protocol_getMethodDescription(self.protocol, selector, YES, YES);
+ if (description.types)
+ return [NSMethodSignature signatureWithObjCTypes:description.types];
+
+ // Look for an optional method in the protocol.
+ description = protocol_getMethodDescription(self.protocol, selector, NO, YES);
+ if (description.types)
+ return [NSMethodSignature signatureWithObjCTypes:description.types];
+
+ // There is neither a required nor optional method with this selector in the
+ // protocol, so invoke -[NSObject doesNotRecognizeSelector:] to raise
+ // NSInvalidArgumentException.
+ [self doesNotRecognizeSelector:selector];
+ return nil;
+}
+
+- (void)forwardInvocation:(NSInvocation*)invocation {
+ SEL selector = [invocation selector];
+ base::scoped_nsobject<NSArray> observers([[_observers allObjects] retain]);
+ for (id observer in observers.get()) {
+ if ([observer respondsToSelector:selector])
+ [invocation invokeWithTarget:observer];
+ }
+}
+
+- (void)executeOnObservers:(ExecutionWithObserverBlock)callback {
+ DCHECK(callback);
+ base::scoped_nsobject<NSArray> observers([[_observers allObjects] retain]);
+ for (id observer in observers.get()) {
+ callback(observer);
+ }
+}
+
+@end
« no previous file with comments | « base/ios/crb_protocol_observers.h ('k') | base/ios/crb_protocol_observers_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698