| Index: ios/web/weak_nsobject_counter.mm
|
| diff --git a/ios/web/weak_nsobject_counter.mm b/ios/web/weak_nsobject_counter.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..bd14b7b3f0180ae2cd6d7d7dd95883617d343be8
|
| --- /dev/null
|
| +++ b/ios/web/weak_nsobject_counter.mm
|
| @@ -0,0 +1,83 @@
|
| +// 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 "ios/web/weak_nsobject_counter.h"
|
| +
|
| +#import <objc/runtime.h>
|
| +
|
| +#include "base/logging.h"
|
| +#import "base/mac/scoped_nsobject.h"
|
| +
|
| +namespace {
|
| +// The key needed for objc_setAssociatedObject. Any value will do, because the
|
| +// address is the key.
|
| +const char kObserverAssociatedObjectKey = 'h';
|
| +}
|
| +
|
| +// Used for observing the objects tracked in the WeakNSObjectCounter. This
|
| +// object will be dealloced when the tracked object is dealloced and will
|
| +// notify the shared counter.
|
| +@interface CRBWeakNSObjectDeallocationObserver : NSObject
|
| +// Designated initializer. |object| cannot be nil. It registers self as an
|
| +// associated object to |object|.
|
| +- (instancetype)initWithSharedCounter:(const linked_ptr<NSUInteger>&)counter
|
| + objectToBeObserved:(id)object;
|
| +@end
|
| +
|
| +@implementation CRBWeakNSObjectDeallocationObserver {
|
| + linked_ptr<NSUInteger> _counter;
|
| +}
|
| +
|
| +- (instancetype)init {
|
| + NOTREACHED();
|
| + return nil;
|
| +}
|
| +
|
| +- (instancetype)initWithSharedCounter:(const linked_ptr<NSUInteger>&)counter
|
| + objectToBeObserved:(id)object {
|
| + self = [super init];
|
| + if (self) {
|
| + DCHECK(counter.get());
|
| + DCHECK(object);
|
| + _counter = counter;
|
| + objc_setAssociatedObject(object, &kObserverAssociatedObjectKey, self,
|
| + OBJC_ASSOCIATION_RETAIN);
|
| + (*_counter)++;
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +- (void)dealloc {
|
| + DCHECK(_counter.get());
|
| + (*_counter)--;
|
| + _counter.reset();
|
| + [super dealloc];
|
| +}
|
| +
|
| +@end
|
| +
|
| +namespace web {
|
| +
|
| +WeakNSObjectCounter::WeakNSObjectCounter() : counter_(new NSUInteger(0)) {
|
| +}
|
| +
|
| +WeakNSObjectCounter::~WeakNSObjectCounter() {
|
| + DCHECK(CalledOnValidThread());
|
| +}
|
| +
|
| +void WeakNSObjectCounter::Insert(id object) {
|
| + DCHECK(CalledOnValidThread());
|
| + DCHECK(object);
|
| + // Create an associated object and register it with |object|.
|
| + base::scoped_nsobject<CRBWeakNSObjectDeallocationObserver> observingObject(
|
| + [[CRBWeakNSObjectDeallocationObserver alloc]
|
| + initWithSharedCounter:counter_ objectToBeObserved:object]);
|
| +}
|
| +
|
| +NSUInteger WeakNSObjectCounter::Size() const {
|
| + DCHECK(CalledOnValidThread());
|
| + return *counter_;
|
| +}
|
| +
|
| +} // namespace web
|
|
|