Skip to content

Commit 5911099

Browse files
committed
Move the class map to a CFDictionary.
Since the keys are `Class`-s, there's no need to hash/copy/etc. them. This avoids causing `+initialize` on the classes just when building up a registry.
1 parent 133e5e7 commit 5911099

File tree

1 file changed

+25
-24
lines changed

1 file changed

+25
-24
lines changed

objectivec/GPBExtensionRegistry.m

+25-24
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,20 @@
3434
#import "GPBDescriptor.h"
3535

3636
@implementation GPBExtensionRegistry {
37-
NSMutableDictionary *mutableClassMap_;
37+
CFMutableDictionaryRef mutableClassMap_;
3838
}
3939

4040
- (instancetype)init {
4141
if ((self = [super init])) {
42-
mutableClassMap_ = [[NSMutableDictionary alloc] init];
42+
// The keys are ObjC classes, so straight up ptr comparisons are fine.
43+
mutableClassMap_ = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL,
44+
&kCFTypeDictionaryValueCallBacks);
4345
}
4446
return self;
4547
}
4648

4749
- (void)dealloc {
48-
[mutableClassMap_ release];
50+
CFRelease(mutableClassMap_);
4951
[super dealloc];
5052
}
5153

@@ -68,14 +70,13 @@ - (void)addExtension:(GPBExtensionDescriptor *)extension {
6870

6971
Class containingMessageClass = extension.containingMessageClass;
7072
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
71-
[mutableClassMap_ objectForKey:containingMessageClass];
73+
CFDictionaryGetValue(mutableClassMap_, containingMessageClass);
7274
if (extensionMap == nil) {
7375
// Use a custom dictionary here because the keys are numbers and conversion
7476
// back and forth from NSNumber isn't worth the cost.
7577
extensionMap = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL,
7678
&kCFTypeDictionaryValueCallBacks);
77-
[mutableClassMap_ setObject:(id)extensionMap
78-
forKey:(id<NSCopying>)containingMessageClass];
79+
CFDictionarySetValue(mutableClassMap_, containingMessageClass, extensionMap);
7980
CFRelease(extensionMap);
8081
}
8182

@@ -87,7 +88,7 @@ - (GPBExtensionDescriptor *)extensionForDescriptor:(GPBDescriptor *)descriptor
8788
fieldNumber:(NSInteger)fieldNumber {
8889
Class messageClass = descriptor.messageClass;
8990
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
90-
[mutableClassMap_ objectForKey:messageClass];
91+
CFDictionaryGetValue(mutableClassMap_, messageClass);
9192
ssize_t key = fieldNumber;
9293
GPBExtensionDescriptor *result =
9394
(extensionMap
@@ -101,28 +102,28 @@ static void CopyKeyValue(const void *key, const void *value, void *context) {
101102
CFDictionarySetValue(extensionMap, key, value);
102103
}
103104

105+
static void CopySubDictionary(const void *key, const void *value, void *context) {
106+
CFMutableDictionaryRef mutableClassMap = (CFMutableDictionaryRef)context;
107+
Class containingMessageClass = key;
108+
CFMutableDictionaryRef otherExtensionMap = (CFMutableDictionaryRef)value;
109+
110+
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
111+
CFDictionaryGetValue(mutableClassMap, containingMessageClass);
112+
if (extensionMap == nil) {
113+
extensionMap = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, otherExtensionMap);
114+
CFDictionarySetValue(mutableClassMap, containingMessageClass, extensionMap);
115+
CFRelease(extensionMap);
116+
} else {
117+
CFDictionaryApplyFunction(otherExtensionMap, CopyKeyValue, extensionMap);
118+
}
119+
}
120+
104121
- (void)addExtensions:(GPBExtensionRegistry *)registry {
105122
if (registry == nil) {
106123
// In the case where there are no extensions just ignore.
107124
return;
108125
}
109-
NSMutableDictionary *otherClassMap = registry->mutableClassMap_;
110-
[otherClassMap enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL * stop) {
111-
#pragma unused(stop)
112-
Class containingMessageClass = key;
113-
CFMutableDictionaryRef otherExtensionMap = (CFMutableDictionaryRef)value;
114-
115-
CFMutableDictionaryRef extensionMap = (CFMutableDictionaryRef)
116-
[mutableClassMap_ objectForKey:containingMessageClass];
117-
if (extensionMap == nil) {
118-
extensionMap = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, otherExtensionMap);
119-
[mutableClassMap_ setObject:(id)extensionMap
120-
forKey:(id<NSCopying>)containingMessageClass];
121-
CFRelease(extensionMap);
122-
} else {
123-
CFDictionaryApplyFunction(otherExtensionMap, CopyKeyValue, extensionMap);
124-
}
125-
}];
126+
CFDictionaryApplyFunction(registry->mutableClassMap_, CopySubDictionary, mutableClassMap_);
126127
}
127128

128129
#pragma clang diagnostic pop

0 commit comments

Comments
 (0)