aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AppKit/GTMIBArray.m41
-rw-r--r--AppKit/GTMIBArrayTest.m27
2 files changed, 68 insertions, 0 deletions
diff --git a/AppKit/GTMIBArray.m b/AppKit/GTMIBArray.m
index a522072..a027440 100644
--- a/AppKit/GTMIBArray.m
+++ b/AppKit/GTMIBArray.m
@@ -122,4 +122,45 @@
return [realArray_ mutableCopyWithZone:zone];
}
+// ----------------------------------------------------------------------------
+// On 10.6, being loaded out of a nib causes the object to get hashed and
+// stored off. The implementation of -hash in NSArray then calls -count, which
+// causes this object to latch on to an empty array. So...
+// 1. -hash gets overridden to simply use the class pointer to maintain
+// the -[NSObject hash] contract that equal objects must have the same hash
+// value. This puts the work in isEqual...
+// 2. -isEqual: overide. Objects can't use the NSArray version until all of
+// the outlets have been filled in and the object is truly setup. The best
+// escape for this is to simply do pointer comparison until the outlets are
+// fully setup.
+// 3. awakeFromNib gets overridden to force the initialize of the real array
+// when all the outlets have been filled in.
+//
+// NOTE: The first attempt was to just overide hash, but that only makes the
+// first IBArray in a nib work. The fact that isEqual was falling through to
+// the NSArray version (comparing to empty arrays), prevented all of the
+// IBArrays from being fully loaded from the nib correctly.
+
+- (NSUInteger)hash {
+ return (NSUInteger)(void*)[self class];
+}
+
+- (BOOL)isEqual:(id)anObject {
+ if ([anObject isMemberOfClass:[self class]]) {
+ GTMIBArray *ibArray2 = anObject;
+ if (!realArray_ || !(ibArray2->realArray_)) {
+ // If realArray_ or ibArray2 haven't been fully configured yet, the only
+ // way they can be equal is if they are the same pointer.
+ return (self == anObject);
+ }
+ }
+ return [super isEqual:anObject];
+}
+
+- (void)awakeFromNib {
+ [realArray_ autorelease];
+ realArray_ = nil;
+ [self setupRealArray];
+}
+
@end
diff --git a/AppKit/GTMIBArrayTest.m b/AppKit/GTMIBArrayTest.m
index c4908b3..45ad3fb 100644
--- a/AppKit/GTMIBArrayTest.m
+++ b/AppKit/GTMIBArrayTest.m
@@ -292,6 +292,33 @@
STAssertTrue([fieldsSet isSubsetOfSet:everythingSet], nil);
}
+- (void)testIsEqual {
+ GTMIBArray *ibArray1 =
+ [[[IBArrayTestHelper alloc] initWithObj1:@"a"
+ obj2:@"b"
+ obj3:@"c"
+ obj4:@"d"
+ obj5:@"e"] autorelease];
+ GTMIBArray *ibArray2 =
+ [[[IBArrayTestHelper alloc] initWithObj1:@"f"
+ obj2:@"g"
+ obj3:@"h"
+ obj4:@"i"
+ obj5:@"j"] autorelease];
+
+ STAssertEquals([ibArray1 hash], [ibArray2 hash], nil);
+ STAssertNotEqualObjects(ibArray1, ibArray2, nil);
+
+ NSArray *ibArray1Prime = [[ibArray1 copy] autorelease];
+ NSArray *ibArray2Prime = [[ibArray2 copy] autorelease];
+
+ STAssertTrue(ibArray1 != ibArray1Prime, nil);
+ STAssertTrue(ibArray2 != ibArray2Prime, nil);
+ STAssertNotEqualObjects(ibArray1Prime, ibArray2Prime, nil);
+ STAssertEqualObjects(ibArray1, ibArray1Prime, nil);
+ STAssertEqualObjects(ibArray2, ibArray2Prime, nil);
+}
+
@end
@implementation GTMIBArrayTestWindowController