Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / base / mac / objc_property_releaser.h
blob973d793218b56aeec694d1f453172c72c502ef53
1 // Copyright (c) 2011 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 #ifndef BASE_MAC_OBJC_PROPERTY_RELEASER_H_
6 #define BASE_MAC_OBJC_PROPERTY_RELEASER_H_
8 #import <Foundation/Foundation.h>
10 #include "base/base_export.h"
12 namespace base {
13 namespace mac {
15 // ObjCPropertyReleaser is a C++ class that can automatically release
16 // synthesized Objective-C properties marked "retain" or "copy". The expected
17 // use is to place an ObjCPropertyReleaser object within an Objective-C class
18 // definition. When built with the -fobjc-call-cxx-cdtors compiler option,
19 // the ObjCPropertyReleaser's destructor will be called when the Objective-C
20 // object that owns it is deallocated, and it will send a -release message to
21 // the instance variables backing the appropriate properties. If
22 // -fobjc-call-cxx-cdtors is not in use, ObjCPropertyReleaser's
23 // ReleaseProperties method can be called from -dealloc to achieve the same
24 // effect.
26 // Example usage:
28 // @interface AllaysIBF : NSObject {
29 // @private
30 // NSString* string_;
31 // NSMutableDictionary* dictionary_;
32 // NSString* notAProperty_;
33 // IBFDelegate* delegate_; // weak
35 // // It's recommended to put the class name into the property releaser's
36 // // instance variable name to gracefully handle subclassing, where
37 // // multiple classes in a hierarchy might want their own property
38 // // releasers.
39 // base::mac::ObjCPropertyReleaser propertyReleaser_AllaysIBF_;
40 // }
42 // @property(retain, nonatomic) NSString* string;
43 // @property(copy, nonatomic) NSMutableDictionary* dictionary;
44 // @property(assign, nonatomic) IBFDelegate* delegate;
45 // @property(retain, nonatomic) NSString* autoProp;
47 // @end // @interface AllaysIBF
49 // @implementation AllaysIBF
51 // @synthesize string = string_;
52 // @synthesize dictionary = dictionary_;
53 // @synthesize delegate = delegate_;
54 // @synthesize autoProp;
56 // - (id)init {
57 // if ((self = [super init])) {
58 // // Initialize with [AllaysIBF class]. Never use [self class] because
59 // // in the case of subclassing, it will return the most specific class
60 // // for |self|, which may not be the same as [AllaysIBF class]. This
61 // // would cause AllaysIBF's -.cxx_destruct or -dealloc to release
62 // // instance variables that only exist in subclasses, likely causing
63 // // mass disaster.
64 // propertyReleaser_AllaysIBF_.Init(self, [AllaysIBF class]);
65 // }
66 // return self;
67 // }
69 // @end // @implementation AllaysIBF
71 // When an instance of AllaysIBF is deallocated, the ObjCPropertyReleaser will
72 // send a -release message to string_, dictionary_, and the compiler-created
73 // autoProp instance variables. No -release will be sent to delegate_ as it
74 // is marked "assign" and not "retain" or "copy". No -release will be sent to
75 // notAProperty_ because it doesn't correspond to any declared @property.
77 // Another way of doing this would be to provide a base class that others can
78 // inherit from, and to have the base class' -dealloc walk the property lists
79 // of all subclasses in an object to send the -release messages. Since this
80 // involves a base reaching into its subclasses, it's deemed scary, so don't
81 // do it. ObjCPropertyReleaser's design ensures that the property releaser
82 // will only operate on instance variables in the immediate object in which
83 // the property releaser is placed.
85 class BASE_EXPORT ObjCPropertyReleaser {
86 public:
87 // ObjCPropertyReleaser can only be owned by an Objective-C object, so its
88 // memory is always guaranteed to be 0-initialized. Not defining the default
89 // constructor can prevent an otherwise no-op -.cxx_construct method from
90 // showing up in Objective-C classes that contain a ObjCPropertyReleaser.
92 // Upon destruction (expected to occur from an Objective-C object's
93 // -.cxx_destruct method), release all properties.
94 ~ObjCPropertyReleaser() {
95 ReleaseProperties();
98 // Initialize this object so that it's armed to release the properties of
99 // object |object|, which must be of type |classy|. The class argument must
100 // be supplied separately and cannot be gleaned from the object's own type
101 // because an object will allays identify itself as the most-specific type
102 // that describes it, but the ObjCPropertyReleaser needs to know which class
103 // type in the class hierarchy it's responsible for releasing properties
104 // for. For the same reason, Init must be called with a |classy| argument
105 // initialized using a +class (class) method such as [MyClass class], and
106 // never a -class (instance) method such as [self class].
108 // -.cxx_construct can only call the default constructor, but
109 // ObjCPropertyReleaser needs to know about the Objective-C object that owns
110 // it, so this can't be handled in a constructor, it needs to be a distinct
111 // Init method.
112 void Init(id object, Class classy);
114 // Release all of the properties in object_ defined in class_ as either
115 // "retain" or "copy" and with an identifiable backing instance variable.
116 // Properties must be synthesized to have identifiable instance variables.
117 void ReleaseProperties();
119 private:
120 id object_;
121 Class class_;
124 } // namespace mac
125 } // namespace base
127 #endif // BASE_MAC_OBJC_PROPERTY_RELEASER_H_