aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-11-02 19:35:10 +0000
committerGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-11-02 19:35:10 +0000
commit0a1e63215324bdc7379e49ed2c9c6dee7f43a6b0 (patch)
treea247b74fbd7bfe4f7418584fa4074094a3e8433a
parente1c938bc73510d64b908408bf404eb10a419001e (diff)
[Author: thomasvl]
Fix up GTMIBArray to work with 10.6 nib loading. Nib loading on 10.6 pushes all objects into hash maps, which caused the IBArray to latch on to its empty state, so this provides overrides so they maintain the contacts around hash and isEqual, but can't be loaded from a nib. R=dmaclach,stuartmorgan DELTA=68 (68 added, 0 deleted, 0 changed)
-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