1#import <Foundation/Foundation.h>
2
3// SourceBase will be the base class of Source. We'll pass a Source object into a
4// function as a SourceBase, and then see if the dynamic typing can get us through the KVO
5// goo and all the way back to Source.
6
7@interface SourceBase: NSObject
8{
9 uint32_t _value;
10}
11- (SourceBase *) init;
12- (uint32_t) getValue;
13@end
14
15@implementation SourceBase
16- (SourceBase *) init
17{
18 [super init];
19 _value = 10;
20 return self;
21}
22- (uint32_t) getValue
23{
24 return _value;
25}
26@end
27
28// Source is a class that will be observed by the Observer class below.
29// When Observer sets itself up to observe this property (in initWithASource)
30// the KVO system will overwrite the "isa" pointer of the object with the "kvo'ed"
31// one.
32
33@interface Source : SourceBase
34{
35 int _property;
36}
37- (Source *) init;
38- (void) setProperty: (int) newValue;
39@end
40
41@implementation Source
42- (Source *) init
43{
44 [super init];
45 _property = 20;
46 return self;
47}
48- (void) setProperty: (int) newValue
49{
50 _property = newValue; // This is the line in setProperty, make sure we step to here.
51}
52@end
53
54@interface SourceDerived : Source
55{
56 int _derivedValue;
57}
58- (SourceDerived *) init;
59- (uint32_t) getValue;
60@end
61
62@implementation SourceDerived
63- (SourceDerived *) init
64{
65 [super init];
66 _derivedValue = 30;
67 return self;
68}
69- (uint32_t) getValue
70{
71 return _derivedValue;
72}
73@end
74
75// Observer is the object that will watch Source and cause KVO to swizzle it...
76
77@interface Observer : NSObject
78{
79 Source *_source;
80}
81+ (Observer *) observerWithSource: (Source *) source;
82- (Observer *) initWithASource: (Source *) source;
83- (void) observeValueForKeyPath: (NSString *) path
84 ofObject: (id) object
85 change: (NSDictionary *) change
86 context: (void *) context;
87@end
88
89@implementation Observer
90
91+ (Observer *) observerWithSource: (Source *) inSource;
92{
93 Observer *retval;
94
95 retval = [[Observer alloc] initWithASource: inSource];
96 return retval;
97}
98
99- (Observer *) initWithASource: (Source *) source
100{
101 [super init];
102 _source = source;
103 [_source addObserver: self
104 forKeyPath: @"property"
105 options: (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
106 context: NULL];
107 return self;
108}
109
110- (void) observeValueForKeyPath: (NSString *) path
111 ofObject: (id) object
112 change: (NSDictionary *) change
113 context: (void *) context
114{
115 printf ("Observer function called.\n");
116 return;
117}
118@end
119
120uint32_t
121handle_SourceBase (SourceBase *object)
122{
123 return [object getValue]; // Break here to check dynamic values.
124}
125
126int main ()
127{
128 Source *mySource;
129 Observer *myObserver;
130
131 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
132
133 mySource = [[SourceDerived alloc] init];
134 myObserver = [Observer observerWithSource: mySource];
135
136 [mySource setProperty: 5]; // Break here to see if we can step into real method.
137
138 uint32_t return_value = handle_SourceBase (mySource);
139
140 SourceDerived *unwatchedSource = [[SourceDerived alloc] init];
141
142 return_value = handle_SourceBase (unwatchedSource);
143
144 [pool release];
145 return 0;
146
147}
148

source code of lldb/test/API/lang/objc/objc-dynamic-value/dynamic-value.m