Permalink
Browse files

Add optimized functions for creating selectors using property keys

  • Loading branch information...
1 parent 66e186e commit c7cea15795d5a96909b338a846d34bb8d9a49194 @jspahrsummers jspahrsummers committed Mar 12, 2013
Showing with 84 additions and 3 deletions.
  1. +11 −3 Mantle.xcodeproj/project.pbxproj
  2. +31 −0 Mantle/MTLReflection.h
  3. +42 −0 Mantle/MTLReflection.m
@@ -40,6 +40,8 @@
D042FC8815F72BC7004E8054 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D042FC5515F72B23004E8054 /* SenTestingKit.framework */; };
D042FC8B15F72BC7004E8054 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D042FC4415F72B23004E8054 /* Foundation.framework */; };
D042FC8E15F72BC7004E8054 /* libMantle.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D042FC7915F72BC7004E8054 /* libMantle.a */; };
+ D058FE2116EFB3D2009DFB47 /* MTLReflection.m in Sources */ = {isa = PBXBuildFile; fileRef = D058FE1E16EFB3D2009DFB47 /* MTLReflection.m */; };
+ D058FE2216EFB3D2009DFB47 /* MTLReflection.m in Sources */ = {isa = PBXBuildFile; fileRef = D058FE1E16EFB3D2009DFB47 /* MTLReflection.m */; };
D064BA341613BA75004CA27A /* MTLTestNotificationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = D064BA331613BA75004CA27A /* MTLTestNotificationObserver.m */; };
D064BA351613BA75004CA27A /* MTLTestNotificationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = D064BA331613BA75004CA27A /* MTLTestNotificationObserver.m */; };
D0760E0515FFBD440060F550 /* Mantle.h in Headers */ = {isa = PBXBuildFile; fileRef = D042FC4C15F72B23004E8054 /* Mantle.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -226,6 +228,8 @@
D042FCB215F72C16004E8054 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = "<group>"; };
D042FCCB15F72EE8004E8054 /* Expecta.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Expecta.xcodeproj; path = MantleTests/expecta/Expecta.xcodeproj; sourceTree = "<group>"; };
D042FCEE15F72EF1004E8054 /* Specta.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Specta.xcodeproj; path = MantleTests/specta/Specta.xcodeproj; sourceTree = "<group>"; };
+ D058FE1D16EFB3D2009DFB47 /* MTLReflection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTLReflection.h; sourceTree = "<group>"; };
+ D058FE1E16EFB3D2009DFB47 /* MTLReflection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTLReflection.m; sourceTree = "<group>"; };
D064BA321613BA75004CA27A /* MTLTestNotificationObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTLTestNotificationObserver.h; sourceTree = "<group>"; };
D064BA331613BA75004CA27A /* MTLTestNotificationObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTLTestNotificationObserver.m; sourceTree = "<group>"; };
D0760E7615FFBF330060F550 /* MTLModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTLModel.h; sourceTree = "<group>"; };
@@ -350,7 +354,7 @@
isa = PBXGroup;
children = (
D042FC4C15F72B23004E8054 /* Mantle.h */,
- D0760E7015FFBF020060F550 /* Classes */,
+ D0760E7015FFBF020060F550 /* Modules */,
D090E62515F730B2005282F9 /* Extensions */,
D042FC4615F72B23004E8054 /* Supporting Files */,
);
@@ -454,17 +458,19 @@
path = "Mac OS X";
sourceTree = "<group>";
};
- D0760E7015FFBF020060F550 /* Classes */ = {
+ D0760E7015FFBF020060F550 /* Modules */ = {
isa = PBXGroup;
children = (
D0760E7615FFBF330060F550 /* MTLModel.h */,
D0760E7715FFBF330060F550 /* MTLModel.m */,
D01BD0AD16CB52E800EC95C7 /* MTLModel+NSCoding.h */,
D01BD0AE16CB52E800EC95C7 /* MTLModel+NSCoding.m */,
+ D058FE1D16EFB3D2009DFB47 /* MTLReflection.h */,
+ D058FE1E16EFB3D2009DFB47 /* MTLReflection.m */,
D01BD0AB16CB46B600EC95C7 /* Adapters */,
D01BD0AC16CB46BD00EC95C7 /* Value Transformers */,
);
- name = Classes;
+ name = Modules;
sourceTree = "<group>";
};
D0760EC615FFCA3E0060F550 /* Specs */ = {
@@ -817,6 +823,7 @@
1ED5B5D1163A4E3C0072668E /* NSObject+MTLComparisonAdditions.m in Sources */,
D01BD09F16CB432D00EC95C7 /* MTLJSONAdapter.m in Sources */,
D01BD0B116CB52E800EC95C7 /* MTLModel+NSCoding.m in Sources */,
+ D058FE2116EFB3D2009DFB47 /* MTLReflection.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -851,6 +858,7 @@
1ED5B5D2163A4E3C0072668E /* NSObject+MTLComparisonAdditions.m in Sources */,
D01BD0A016CB432D00EC95C7 /* MTLJSONAdapter.m in Sources */,
D01BD0B216CB52E800EC95C7 /* MTLModel+NSCoding.m in Sources */,
+ D058FE2216EFB3D2009DFB47 /* MTLReflection.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -0,0 +1,31 @@
+//
+// MTLReflection.h
+// Mantle
+//
+// Created by Justin Spahr-Summers on 2013-03-12.
+// Copyright (c) 2013 GitHub. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+// Creates a selector from a key and a constant string.
+//
+// key - The key to insert into the generated selector. This key should be in
+// its natural case.
+// suffix - A string to append to the key as part of the selector.
+//
+// Returns a selector, or NULL if the input strings cannot form a valid
+// selector.
+SEL MTLSelectorWithKeyPattern(NSString *key, NSString *suffix) __attribute__((pure, nonnull(1, 2)));
+
+// Creates a selector from a key and a constant prefix and suffix.
+//
+// prefix - A string to prepend to the key as part of the selector.
+// key - The key to insert into the generated selector. This key should be in
+// its natural case, and will have its first letter capitalized when
+// inserted.
+// suffix - A string to append to the key as part of the selector.
+//
+// Returns a selector, or NULL if the input strings cannot form a valid
+// selector.
+SEL MTLSelectorWithCapitalizedKeyPattern(NSString *prefix, NSString *key, NSString *suffix) __attribute__((pure, nonnull(1, 2, 3)));
@@ -0,0 +1,42 @@
+//
+// MTLReflection.m
+// Mantle
+//
+// Created by Justin Spahr-Summers on 2013-03-12.
+// Copyright (c) 2013 GitHub. All rights reserved.
+//
+
+#import "MTLReflection.h"
+#import <objc/runtime.h>
+
+SEL MTLSelectorWithKeyPattern(NSString *key, NSString *suffix) {
+ NSUInteger keyLength = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+ NSUInteger suffixLength = [suffix lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+
+ char selector[keyLength + suffixLength + 1];
+ memcpy(selector, key.UTF8String, keyLength);
+ memcpy(selector + keyLength, suffix.UTF8String, suffixLength);
+ selector[sizeof(selector) - 1] = '\0';
+
+ return sel_registerName(selector);
+}
+
+SEL MTLSelectorWithCapitalizedKeyPattern(NSString *prefix, NSString *key, NSString *suffix) {
+ NSUInteger prefixLength = [prefix lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+ NSUInteger suffixLength = [suffix lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+
+ NSString *initial = [key substringToIndex:1].uppercaseString;
+ NSUInteger initialLength = [initial lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+
+ NSString *rest = [key substringFromIndex:1];
+ NSUInteger restLength = [rest lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+
+ char selector[prefixLength + initialLength + restLength + suffixLength + 1];
+ memcpy(selector, prefix.UTF8String, prefixLength);
+ memcpy(selector + prefixLength, initial.UTF8String, initialLength);
+ memcpy(selector + prefixLength + initialLength, rest.UTF8String, restLength);
+ memcpy(selector + prefixLength + initialLength + restLength, suffix.UTF8String, suffixLength);
+ selector[sizeof(selector) - 1] = '\0';
+
+ return sel_registerName(selector);
+}

0 comments on commit c7cea15

Please sign in to comment.