- add sources.
[platform/framework/web/crosswalk.git] / src / base / mac / objc_property_releaser.h
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.
4
5 #ifndef BASE_MAC_OBJC_PROPERTY_RELEASER_H_
6 #define BASE_MAC_OBJC_PROPERTY_RELEASER_H_
7
8 #import <Foundation/Foundation.h>
9
10 #include "base/base_export.h"
11
12 namespace base {
13 namespace mac {
14
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.
25 //
26 // Example usage:
27 //
28 // @interface AllaysIBF : NSObject {
29 //  @private
30 //   NSString* string_;
31 //   NSMutableDictionary* dictionary_;
32 //   NSString* notAProperty_;
33 //   IBFDelegate* delegate_;  // weak
34 //
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 // }
41 //
42 // @property(retain, nonatomic) NSString* string;
43 // @property(copy, nonatomic) NSMutableDictionary* dictionary;
44 // @property(assign, nonatomic) IBFDelegate* delegate;
45 // @property(retain, nonatomic) NSString* autoProp;
46 //
47 // @end  // @interface AllaysIBF
48 //
49 // @implementation AllaysIBF
50 //
51 // @synthesize string = string_;
52 // @synthesize dictionary = dictionary_;
53 // @synthesize delegate = delegate_;
54 // @synthesize autoProp;
55 //
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 // }
68 //
69 // @end  // @implementation AllaysIBF
70 //
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.
76 //
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.
84
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.
91
92   // Upon destruction (expected to occur from an Objective-C object's
93   // -.cxx_destruct method), release all properties.
94   ~ObjCPropertyReleaser() {
95     ReleaseProperties();
96   }
97
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].
107   //
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);
113
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();
118
119  private:
120   id object_;
121   Class class_;
122 };
123
124 }  // namespace mac
125 }  // namespace base
126
127 #endif  // BASE_MAC_OBJC_PROPERTY_RELEASER_H_