1 | #import <Foundation/Foundation.h> |
2 | #include <stdio.h> |
3 | |
4 | struct return_me |
5 | { |
6 | int first; |
7 | int second; |
8 | }; |
9 | |
10 | @interface SourceBase: NSObject |
11 | { |
12 | struct return_me my_return; |
13 | } |
14 | - (SourceBase *) initWithFirst: (int) first andSecond: (int) second; |
15 | - (void) randomMethod; |
16 | - (struct return_me) returnsStruct; |
17 | @end |
18 | |
19 | @implementation SourceBase |
20 | - (void) randomMethod |
21 | { |
22 | printf (format: "Called in SourceBase version of randomMethod.\n" ); // SourceBase randomMethod start line. |
23 | } |
24 | |
25 | - (struct return_me) returnsStruct |
26 | { |
27 | return my_return; // SourceBase returnsStruct start line. |
28 | } |
29 | |
30 | - (SourceBase *) initWithFirst: (int) first andSecond: (int) second |
31 | { |
32 | my_return.first = first; |
33 | my_return.second = second; |
34 | |
35 | return self; |
36 | } |
37 | @end |
38 | |
39 | @interface Source : SourceBase |
40 | { |
41 | int _property; |
42 | } |
43 | - (void) setProperty: (int) newValue; |
44 | - (void) randomMethod; |
45 | - (struct return_me) returnsStruct; |
46 | @end |
47 | |
48 | @implementation Source |
49 | - (void) setProperty: (int) newValue |
50 | { |
51 | _property = newValue; |
52 | } |
53 | |
54 | - (void) randomMethod |
55 | { |
56 | [super randomMethod]; // Source randomMethod start line. |
57 | printf (format: "Called in Source version of random method." ); |
58 | } |
59 | |
60 | - (struct return_me) returnsStruct |
61 | { |
62 | printf (format: "Called in Source version of returnsStruct.\n" ); // Source returnsStruct start line. |
63 | return [super returnsStruct]; // Source returnsStruct call line. |
64 | } |
65 | |
66 | @end |
67 | |
68 | @interface Observer : NSObject |
69 | { |
70 | Source *_source; |
71 | } |
72 | + (Observer *) observerWithSource: (Source *) source; |
73 | - (Observer *) initWithASource: (Source *) source; |
74 | - (void) observeValueForKeyPath: (NSString *) path |
75 | ofObject: (id) object |
76 | change: (NSDictionary *) change |
77 | context: (void *) context; |
78 | @end |
79 | |
80 | @implementation Observer |
81 | |
82 | + (Observer *) observerWithSource: (Source *) inSource; |
83 | { |
84 | Observer *retval; |
85 | |
86 | retval = [[Observer alloc] initWithASource: inSource]; |
87 | return retval; |
88 | } |
89 | |
90 | - (Observer *) initWithASource: (Source *) source |
91 | { |
92 | [super init]; |
93 | _source = source; |
94 | [_source addObserver: self |
95 | forKeyPath: @"property" |
96 | options: (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) |
97 | context: NULL]; |
98 | return self; |
99 | } |
100 | |
101 | - (void) observeValueForKeyPath: (NSString *) path |
102 | ofObject: (id) object |
103 | change: (NSDictionary *) change |
104 | context: (void *) context |
105 | { |
106 | printf (format: "Observer function called.\n" ); |
107 | return; |
108 | } |
109 | @end |
110 | |
111 | int main () |
112 | { |
113 | Source *mySource; |
114 | Observer *myObserver; |
115 | struct return_me ret_val; |
116 | |
117 | NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; |
118 | |
119 | mySource = [[Source alloc] init]; |
120 | |
121 | [mySource randomMethod]; // Set first breakpoint here. |
122 | ret_val = [mySource returnsStruct]; // Set second breakpoint here. |
123 | |
124 | myObserver = [Observer observerWithSource: mySource]; |
125 | |
126 | [mySource randomMethod]; // Set third breakpoint here. |
127 | ret_val = [mySource returnsStruct]; // Set fourth breakpoint here. |
128 | [mySource setProperty: 5]; // Set fifth breakpoint here. |
129 | |
130 | // We also had a bug where stepping into a method dispatch to nil turned |
131 | // into continue. So make sure that works here: |
132 | |
133 | mySource = nil; |
134 | [mySource randomMethod]; // Set nil step breakpoint here. |
135 | [pool release]; // Step over nil should stop here. |
136 | return 0; |
137 | |
138 | } |
139 | |