1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/ios/weak_nsobject.h"
7 #include "base/mac/scoped_nsautorelease_pool.h"
8 #include "base/mac/scoped_nsobject.h"
11 // The key needed by objc_setAssociatedObject.
12 char sentinelObserverKey_;
15 @interface CRBWeakNSProtocolSentinel ()
16 // Container to notify on dealloc.
17 @property(readonly, assign) scoped_refptr<base::WeakContainer> container;
18 // Designed initializer.
19 - (id)initWithContainer:(scoped_refptr<base::WeakContainer>)container;
22 @implementation CRBWeakNSProtocolSentinel
24 @synthesize container = container_;
26 + (scoped_refptr<base::WeakContainer>)containerForObject:(id)object {
29 // The autoreleasePool is needed here as the call to objc_getAssociatedObject
30 // returns an autoreleased object which is better released sooner than later.
31 base::mac::ScopedNSAutoreleasePool pool;
32 CRBWeakNSProtocolSentinel* sentinel =
33 objc_getAssociatedObject(object, &sentinelObserverKey_);
35 base::scoped_nsobject<CRBWeakNSProtocolSentinel> newSentinel(
36 [[CRBWeakNSProtocolSentinel alloc]
37 initWithContainer:new base::WeakContainer(object)]);
38 sentinel = newSentinel;
39 objc_setAssociatedObject(object, &sentinelObserverKey_, sentinel,
40 OBJC_ASSOCIATION_RETAIN);
41 // The retain count is 2. One retain is due to the alloc, the other to the
42 // association with the weak object.
43 DCHECK_EQ(2u, [sentinel retainCount]);
45 return [sentinel container];
48 - (id)initWithContainer:(scoped_refptr<base::WeakContainer>)container {
49 DCHECK(container.get());
52 container_ = container;
57 self.container->nullify();