2011-02-16 08:21:17 +00:00
|
|
|
#import "ObjectTesting.h"
|
2011-08-03 08:41:26 +00:00
|
|
|
#import <Foundation/Foundation.h>
|
2011-02-16 08:21:17 +00:00
|
|
|
|
2012-07-27 16:48:49 +00:00
|
|
|
typedef struct {
|
|
|
|
int a;
|
|
|
|
float b;
|
|
|
|
char *c;
|
|
|
|
} aStruct;
|
|
|
|
|
2011-02-16 08:21:17 +00:00
|
|
|
@interface Observer : NSObject
|
|
|
|
- (void) observeValueForKeyPath: (NSString *)keyPath
|
|
|
|
ofObject: (id)object
|
|
|
|
change: (NSDictionary *)change
|
|
|
|
context: (void *)context;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation Observer
|
|
|
|
- (void) observeValueForKeyPath: (NSString *)keyPath
|
|
|
|
ofObject: (id)object
|
|
|
|
change: (NSDictionary *)change
|
|
|
|
context: (void *)context
|
|
|
|
{
|
|
|
|
NSLog(@"observeValueForKeyPath: %@\nofObject:%@\nchange:%@\ncontext:%p",
|
|
|
|
keyPath, object, change, context);
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
@interface Lists : NSObject
|
|
|
|
{
|
|
|
|
NSMutableArray * cities;
|
|
|
|
NSMutableArray * numbers;
|
|
|
|
NSMutableArray * third;
|
|
|
|
NSString *string;
|
2012-07-27 16:48:49 +00:00
|
|
|
aStruct x;
|
2011-02-16 08:21:17 +00:00
|
|
|
}
|
|
|
|
|
2012-07-27 16:48:49 +00:00
|
|
|
- (int) a;
|
|
|
|
- (float) b;
|
|
|
|
- (const char*) c;
|
2011-02-16 08:21:17 +00:00
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
@implementation Lists
|
|
|
|
|
2012-07-27 16:48:49 +00:00
|
|
|
- (int) a
|
|
|
|
{
|
|
|
|
return x.a;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (float) b
|
|
|
|
{
|
|
|
|
return x.b;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (const char*) c
|
|
|
|
{
|
|
|
|
return x.c;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) init
|
2011-02-16 08:21:17 +00:00
|
|
|
{
|
|
|
|
cities = [[NSMutableArray alloc] initWithObjects:
|
|
|
|
@"Grand Rapids",
|
|
|
|
@"Chicago",
|
|
|
|
nil];
|
|
|
|
numbers = [[NSMutableArray alloc] initWithObjects:
|
|
|
|
@"One",
|
|
|
|
@"Ten",
|
|
|
|
@"Three",
|
|
|
|
@"Ninety",
|
|
|
|
nil];
|
|
|
|
third = [[NSMutableArray alloc] initWithObjects:
|
|
|
|
@"a",
|
|
|
|
@"b",
|
|
|
|
@"c",
|
|
|
|
nil];
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
- (void) insertObject: (id)obj inNumbersAtIndex: (NSUInteger)index
|
2011-02-16 08:21:17 +00:00
|
|
|
{
|
|
|
|
if (![obj isEqualToString:@"NaN"])
|
|
|
|
{
|
|
|
|
[numbers addObject:obj];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
- (void) removeObjectFromNumbersAtIndex: (NSUInteger)index
|
2011-02-16 08:21:17 +00:00
|
|
|
{
|
|
|
|
if (![[numbers objectAtIndex:index] isEqualToString:@"One"])
|
|
|
|
[numbers removeObjectAtIndex:index];
|
|
|
|
}
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
- (void) replaceObjectInNumbersAtIndex: (NSUInteger)index withObject: (id)obj
|
2011-02-16 08:21:17 +00:00
|
|
|
{
|
|
|
|
if (index == 1)
|
|
|
|
obj = @"Two";
|
|
|
|
[numbers replaceObjectAtIndex:index withObject:obj];
|
|
|
|
}
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
- (void) setCities: (NSArray *)other
|
2011-02-16 08:21:17 +00:00
|
|
|
{
|
|
|
|
[cities setArray:other];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) didChangeValueForKey: (NSString*)k
|
|
|
|
{
|
|
|
|
NSLog(@"%@ %@", NSStringFromSelector(_cmd), k);
|
|
|
|
[super didChangeValueForKey: k];
|
|
|
|
}
|
|
|
|
|
2012-07-27 16:48:49 +00:00
|
|
|
- (void) setX: (aStruct)s
|
|
|
|
{
|
|
|
|
x = s;
|
|
|
|
}
|
|
|
|
|
2011-02-16 08:21:17 +00:00
|
|
|
- (void) willChangeValueForKey: (NSString*)k
|
|
|
|
{
|
|
|
|
[super willChangeValueForKey: k];
|
|
|
|
NSLog(@"%@ %@", NSStringFromSelector(_cmd), k);
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
@interface Sets : NSObject
|
|
|
|
{
|
|
|
|
NSMutableSet * one;
|
|
|
|
NSMutableSet * two;
|
|
|
|
NSMutableSet * three;
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation Sets
|
|
|
|
|
|
|
|
- (id)init
|
|
|
|
{
|
|
|
|
[super init];
|
|
|
|
|
|
|
|
one = [[NSMutableSet alloc] initWithObjects:
|
|
|
|
@"one",
|
|
|
|
@"two",
|
|
|
|
@"eight",
|
|
|
|
nil];
|
|
|
|
two = [[NSMutableSet alloc] initWithSet:one];
|
|
|
|
three = [[NSMutableSet alloc] initWithSet:one];
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
- (void) addOneObject: (id)anObject
|
2011-02-16 08:21:17 +00:00
|
|
|
{
|
|
|
|
if (![anObject isEqualToString:@"ten"])
|
|
|
|
[one addObject:anObject];
|
|
|
|
}
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
- (void) removeOneObject: (id)anObject
|
2011-02-16 08:21:17 +00:00
|
|
|
{
|
|
|
|
if (![anObject isEqualToString:@"one"])
|
|
|
|
{
|
|
|
|
[one removeObject:anObject];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
- (void) setTwo: (NSMutableSet *)set
|
2011-02-16 08:21:17 +00:00
|
|
|
{
|
|
|
|
[two setSet:set];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
int main(void)
|
|
|
|
{
|
|
|
|
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
|
|
|
|
|
|
|
Lists *list = [[[Lists alloc] init] autorelease];
|
|
|
|
Observer *observer = [Observer new];
|
2012-07-27 16:48:49 +00:00
|
|
|
aStruct s = {1, 2, "3" };
|
2011-02-16 08:21:17 +00:00
|
|
|
id o;
|
|
|
|
NSMutableArray * proxy;
|
|
|
|
NSDictionary * temp;
|
|
|
|
|
|
|
|
[list addObserver: observer forKeyPath: @"numbers" options: 15 context: 0];
|
|
|
|
[list addObserver: observer forKeyPath: @"string" options: 15 context: 0];
|
2012-07-27 16:48:49 +00:00
|
|
|
[list addObserver: observer forKeyPath: @"x" options: 15 context: 0];
|
2011-02-16 08:21:17 +00:00
|
|
|
|
|
|
|
[list setValue: @"x" forKey: @"string"];
|
|
|
|
|
|
|
|
proxy = [list mutableArrayValueForKey:@"numbers"];
|
|
|
|
PASS([proxy isKindOfClass:[NSMutableArray class]],
|
|
|
|
"proxy is a kind of NSMutableArray")
|
|
|
|
[proxy removeLastObject];
|
2016-06-22 09:43:00 +00:00
|
|
|
PASS_EXCEPTION([proxy addObject: @"NaN"];,
|
2011-02-16 08:21:17 +00:00
|
|
|
NSRangeException,"bad removal causes range exception when observing")
|
2016-06-22 09:43:00 +00:00
|
|
|
[proxy replaceObjectAtIndex: 1 withObject: @"Seven"];
|
|
|
|
[proxy addObject: @"Four"];
|
|
|
|
[proxy removeObject: @"One"];
|
2011-02-16 08:21:17 +00:00
|
|
|
|
|
|
|
o = [NSArray arrayWithObjects:
|
|
|
|
@"One",
|
|
|
|
@"Two",
|
|
|
|
@"Three",
|
|
|
|
@"Four",
|
|
|
|
nil];
|
2016-06-22 09:43:00 +00:00
|
|
|
PASS([[list valueForKey: @"numbers"] isEqualToArray: o],
|
2011-02-16 08:21:17 +00:00
|
|
|
"KVC mutableArrayValueForKey: proxy works with array proxy methods")
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
proxy = [list mutableArrayValueForKey: @"cities"];
|
|
|
|
PASS([proxy isKindOfClass: [NSMutableArray class]],
|
2011-02-16 08:21:17 +00:00
|
|
|
"proxy is a kind of NSMutableArray")
|
2016-06-22 09:43:00 +00:00
|
|
|
[proxy addObject: @"Lima"];
|
2011-02-16 08:21:17 +00:00
|
|
|
o = [NSArray arrayWithObjects:
|
|
|
|
@"Grand Rapids",
|
|
|
|
@"Chicago",
|
|
|
|
@"Lima",
|
|
|
|
nil];
|
2016-06-22 09:43:00 +00:00
|
|
|
PASS([[list valueForKey: @"cities"] isEqualToArray: o],
|
2011-02-16 08:21:17 +00:00
|
|
|
"KVC mutableArrayValueForKey: proxy works with set<Key>:")
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
proxy = [list mutableArrayValueForKey: @"third"];
|
|
|
|
PASS([proxy isKindOfClass: [NSMutableArray class]],
|
2011-02-16 08:21:17 +00:00
|
|
|
"proxy is a kind of NSMutableArray")
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
PASS(proxy != [list valueForKey: @"third"],
|
2011-02-16 08:21:17 +00:00
|
|
|
"KVC mutableArrayValueForKey: returns a proxy array for the ivar")
|
2016-06-22 09:43:00 +00:00
|
|
|
PASS([[proxy objectAtIndex: 1] isEqualToString: @"b"],
|
2011-02-16 08:21:17 +00:00
|
|
|
"This proxy works")
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
temp = [NSDictionary dictionaryWithObject: list forKey: @"list"];
|
|
|
|
proxy = [temp mutableArrayValueForKeyPath: @"list.numbers"];
|
|
|
|
PASS([proxy isKindOfClass: NSClassFromString(@"NSKeyValueMutableArray")],
|
2011-02-16 08:21:17 +00:00
|
|
|
"mutableArrayValueForKey: works")
|
|
|
|
|
|
|
|
|
|
|
|
Sets * set = [[[Sets alloc] init] autorelease];
|
|
|
|
NSMutableSet * setProxy;
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
setProxy = [set mutableSetValueForKey: @"one"];
|
|
|
|
PASS([setProxy isKindOfClass: [NSMutableSet class]],
|
2011-02-16 08:21:17 +00:00
|
|
|
"proxy is a kind of NSMutableSet")
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
[setProxy removeObject: @"one"];
|
|
|
|
[setProxy addObject: @"ten"];
|
|
|
|
[setProxy removeObject: @"eight"];
|
|
|
|
[setProxy addObject: @"three"];
|
2011-02-16 08:21:17 +00:00
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
o = [NSSet setWithObjects: @"one", @"two", @"three", nil];
|
2011-02-16 08:21:17 +00:00
|
|
|
PASS([setProxy isEqualToSet: o],
|
|
|
|
"KVC mutableSetValueForKey: proxy uses methods")
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
setProxy = [set mutableSetValueForKey: @"two"];
|
|
|
|
PASS([setProxy isKindOfClass: [NSMutableSet class]],
|
2011-02-16 08:21:17 +00:00
|
|
|
"proxy is a kind of NSMutableSet")
|
2016-06-22 09:43:00 +00:00
|
|
|
[setProxy addObject: @"seven"];
|
|
|
|
[setProxy minusSet: [NSSet setWithObject: @"eight"]];
|
|
|
|
o = [NSSet setWithObjects: @"one", @"two", @"seven", nil];
|
|
|
|
PASS([setProxy isEqualToSet: o],
|
2011-02-16 08:21:17 +00:00
|
|
|
"KVC mutableSetValueForKey: proxy works with set<Key>:")
|
|
|
|
|
2016-06-22 09:43:00 +00:00
|
|
|
setProxy = [set mutableSetValueForKey: @"three"];
|
|
|
|
PASS([setProxy isKindOfClass: [NSMutableSet class]],
|
2011-02-16 08:21:17 +00:00
|
|
|
"proxy is kind of NSMutableSet")
|
2016-06-22 09:43:00 +00:00
|
|
|
PASS(setProxy != [set valueForKey: @"three"],
|
2011-02-16 08:21:17 +00:00
|
|
|
"KVC mutableSetValueForKey: returns a proxy set for the ivar")
|
2016-06-22 09:43:00 +00:00
|
|
|
[setProxy addObject: @"seven"];
|
|
|
|
[setProxy removeObject: @"eight"];
|
|
|
|
o = [NSSet setWithObjects: @"one", @"two", @"seven", nil];
|
|
|
|
PASS([setProxy isEqualToSet: o], "this proxy works")
|
|
|
|
|
|
|
|
temp = [NSDictionary dictionaryWithObject: set forKey: @"set"];
|
|
|
|
setProxy = [temp mutableSetValueForKeyPath: @"set.three"];
|
|
|
|
PASS([setProxy isKindOfClass: NSClassFromString(@"NSKeyValueMutableSet")],
|
2011-02-16 08:21:17 +00:00
|
|
|
"mutableSetValueForKey: works")
|
|
|
|
|
2012-07-27 16:48:49 +00:00
|
|
|
[list setX: s];
|
|
|
|
PASS([list a] == 1 && [list b] == 2.0 && strcmp([list c], "3") == 0,
|
|
|
|
"able to set struct");
|
|
|
|
|
2011-02-16 08:21:17 +00:00
|
|
|
[list removeObserver: observer forKeyPath: @"numbers"];
|
|
|
|
[list removeObserver: observer forKeyPath: @"string"];
|
2012-07-27 16:48:49 +00:00
|
|
|
[list removeObserver: observer forKeyPath: @"x"];
|
2011-02-16 08:21:17 +00:00
|
|
|
|
|
|
|
[arp release]; arp = nil;
|
|
|
|
return 0;
|
|
|
|
}
|