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