| Index: base/ios/weak_nsobject.mm
|
| diff --git a/base/ios/weak_nsobject.mm b/base/ios/weak_nsobject.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..36f9d3ea7cdd700da53d77a34245c3bad68a86c1
|
| --- /dev/null
|
| +++ b/base/ios/weak_nsobject.mm
|
| @@ -0,0 +1,61 @@
|
| +// Copyright 2013 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.
|
| +
|
| +#include "base/ios/weak_nsobject.h"
|
| +
|
| +#include "base/mac/scoped_nsautorelease_pool.h"
|
| +#include "base/mac/scoped_nsobject.h"
|
| +
|
| +namespace {
|
| +// The key needed by objc_setAssociatedObject.
|
| +char sentinelObserverKey_;
|
| +}
|
| +
|
| +@interface CRBWeakNSProtocolSentinel ()
|
| +// Container to notify on dealloc.
|
| +@property(readonly, assign) scoped_refptr<base::WeakContainer> container;
|
| +// Designed initializer.
|
| +- (id)initWithContainer:(scoped_refptr<base::WeakContainer>)container;
|
| +@end
|
| +
|
| +@implementation CRBWeakNSProtocolSentinel
|
| +
|
| +@synthesize container = container_;
|
| +
|
| ++ (scoped_refptr<base::WeakContainer>)containerForObject:(id)object {
|
| + if (object == nil)
|
| + return nullptr;
|
| + // The autoreleasePool is needed here as the call to objc_getAssociatedObject
|
| + // returns an autoreleased object which is better released sooner than later.
|
| + base::mac::ScopedNSAutoreleasePool pool;
|
| + CRBWeakNSProtocolSentinel* sentinel =
|
| + objc_getAssociatedObject(object, &sentinelObserverKey_);
|
| + if (!sentinel) {
|
| + base::scoped_nsobject<CRBWeakNSProtocolSentinel> newSentinel(
|
| + [[CRBWeakNSProtocolSentinel alloc]
|
| + initWithContainer:new base::WeakContainer(object)]);
|
| + sentinel = newSentinel;
|
| + objc_setAssociatedObject(object, &sentinelObserverKey_, sentinel,
|
| + OBJC_ASSOCIATION_RETAIN);
|
| + // The retain count is 2. One retain is due to the alloc, the other to the
|
| + // association with the weak object.
|
| + DCHECK_EQ(2u, [sentinel retainCount]);
|
| + }
|
| + return [sentinel container];
|
| +}
|
| +
|
| +- (id)initWithContainer:(scoped_refptr<base::WeakContainer>)container {
|
| + DCHECK(container.get());
|
| + self = [super init];
|
| + if (self)
|
| + container_ = container;
|
| + return self;
|
| +}
|
| +
|
| +- (void)dealloc {
|
| + self.container->nullify();
|
| + [super dealloc];
|
| +}
|
| +
|
| +@end
|
|
|