150 lines · plain
1#import <Foundation/Foundation.h>2 3// SourceBase will be the base class of Source. We'll pass a Source object into a4// function as a SourceBase, and then see if the dynamic typing can get us through the KVO5// goo and all the way back to Source.6 7@interface SourceBase: NSObject8{9 uint32_t _value;10}11- (SourceBase *) init;12- (uint32_t) getValue;13@end14 15@implementation SourceBase16- (SourceBase *) init17{18 [super init];19 _value = 10;20 return self;21}22- (uint32_t) getValue23{24 return _value;25}26@end27 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 : SourceBase34{35 int _property;36}37- (Source *) init;38- (void) setProperty: (int) newValue;39@end40 41@implementation Source42- (Source *) init43{44 [super init];45 _property = 20;46 return self;47}48- (void) setProperty: (int) newValue49{50 _property = newValue; // This is the line in setProperty, make sure we step to here.51}52@end53 54@interface SourceDerived : Source55{56 int _derivedValue;57}58- (SourceDerived *) init;59- (uint32_t) getValue;60@end61 62@implementation SourceDerived63- (SourceDerived *) init64{65 [super init];66 _derivedValue = 30;67 return self;68}69- (uint32_t) getValue70{71 return _derivedValue;72}73@end74 75// Observer is the object that will watch Source and cause KVO to swizzle it...76 77@interface Observer : NSObject78{79 Source *_source;80}81+ (Observer *) observerWithSource: (Source *) source;82- (Observer *) initWithASource: (Source *) source;83- (void) observeValueForKeyPath: (NSString *) path 84 ofObject: (id) object85 change: (NSDictionary *) change86 context: (void *) context;87@end88 89@implementation Observer90 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 *) source100{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) object112 change: (NSDictionary *) change113 context: (void *) context114{115 printf ("Observer function called.\n");116 return;117}118@end119 120 121int patval; // external symbol, will not be completely stripped122int pat(int in) { // external symbol, will not be completely stripped123 if (patval == 0)124 patval = in;125 return patval;126}127 128static int fooval; // static symbol, stripped129int foo() { // external symbol, will not be completely stripped130 if (fooval == 0)131 fooval = 5;132 return fooval;133}134 135int bazval = 10; // external symbol, will not be completely stripped136int baz () { // external symbol, will not be completely stripped137 return foo() + bazval;138}139 140static int barval = 15; // static symbol, stripped141static int bar () { // static symbol, stripped; __lldb_unnamed_symbol from func starts142 return baz() + barval;143}144 145int calculate () // external symbol, will not be completely stripped146{147 return bar();148}149 150