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 ("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 ("Called in Source version of random method."); 58 } 59 60 - (struct return_me) returnsStruct 61 { 62 printf ("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 ("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