Permalink
Browse files

Play with trampolining.

  • Loading branch information...
1 parent 022d40a commit 4b7b31ca9c90055fd2984c4b5645942a4d3fd35f @mudphone committed Apr 15, 2012
@@ -10,6 +10,7 @@
CF248ACE15313261006D0732 /* NSNotificationCenter+RNSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = CF248ACB15313261006D0732 /* NSNotificationCenter+RNSwizzle.m */; };
CF248ACF15313261006D0732 /* RNSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = CF248ACD15313261006D0732 /* RNSwizzle.m */; };
CF248BF915345A87006D0732 /* NSArray+Clojureizer.m in Sources */ = {isa = PBXBuildFile; fileRef = CF248BF815345A87006D0732 /* NSArray+Clojureizer.m */; };
+ CF248C00153534CC006D0732 /* PDCArrayMapProxyNormal.m in Sources */ = {isa = PBXBuildFile; fileRef = CF248BFF153534CC006D0732 /* PDCArrayMapProxyNormal.m */; };
CFA73E631522385300625A31 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFA73E621522385300625A31 /* UIKit.framework */; };
CFA73E651522385300625A31 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFA73E641522385300625A31 /* Foundation.framework */; };
CFA73E671522385300625A31 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFA73E661522385300625A31 /* CoreGraphics.framework */; };
@@ -27,6 +28,8 @@
CF248ACD15313261006D0732 /* RNSwizzle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSwizzle.m; sourceTree = "<group>"; };
CF248BF715345A87006D0732 /* NSArray+Clojureizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Clojureizer.h"; sourceTree = "<group>"; };
CF248BF815345A87006D0732 /* NSArray+Clojureizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Clojureizer.m"; sourceTree = "<group>"; };
+ CF248BFE153534CC006D0732 /* PDCArrayMapProxyNormal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDCArrayMapProxyNormal.h; sourceTree = "<group>"; };
+ CF248BFF153534CC006D0732 /* PDCArrayMapProxyNormal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDCArrayMapProxyNormal.m; sourceTree = "<group>"; };
CFA73E5E1522385300625A31 /* ObjcPlayground.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ObjcPlayground.app; sourceTree = BUILT_PRODUCTS_DIR; };
CFA73E621522385300625A31 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
CFA73E641522385300625A31 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
@@ -65,6 +68,8 @@
CF248ACD15313261006D0732 /* RNSwizzle.m */,
CF248BF715345A87006D0732 /* NSArray+Clojureizer.h */,
CF248BF815345A87006D0732 /* NSArray+Clojureizer.m */,
+ CF248BFE153534CC006D0732 /* PDCArrayMapProxyNormal.h */,
+ CF248BFF153534CC006D0732 /* PDCArrayMapProxyNormal.m */,
);
name = "Collection Enhancements";
sourceTree = "<group>";
@@ -191,6 +196,7 @@
CF248ACE15313261006D0732 /* NSNotificationCenter+RNSwizzle.m in Sources */,
CF248ACF15313261006D0732 /* RNSwizzle.m in Sources */,
CF248BF915345A87006D0732 /* NSArray+Clojureizer.m in Sources */,
+ CF248C00153534CC006D0732 /* PDCArrayMapProxyNormal.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -7,6 +7,7 @@
//
#import "NSArray+Clojureizer.h"
+#import "HOM.h"
@implementation NSArray (Clojureizer)
@@ -10,4 +10,9 @@
@interface PDCArrayMapProxyNormal : NSProxy
+@property (nonatomic, strong) NSArray *array;
+
+- (id)initWithArray:(NSArray *)array;
+
+
@end
@@ -8,6 +8,32 @@
#import "PDCArrayMapProxyNormal.h"
+
@implementation PDCArrayMapProxyNormal
-@end
+@synthesize array = _array;
+
+- (id)initWithArray:(NSArray *)array
+{
+ _array = array;
+ return self;
+}
+
+- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
+{
+ return [[_array lastObject] methodSignatureForSelector:sel];
+}
+
+- (void)forwardInvocation:(NSInvocation *)inv
+{
+ NSMutableArray *newArray = [NSMutableArray array];
+ for(id obj in _array)
+ {
+ id retval;
+ [inv invokeWithTarget:obj];
+ [inv getReturnValue:&retval];
+ [newArray addObject:retval];
+ }
+ [inv setReturnValue:&newArray];
+}
+@end
@@ -7,6 +7,7 @@
//
#import "PDCViewController.h"
+#import "PDCArrayMapProxyNormal.h"
#import <objc/objc-runtime.h>
#import "NSArray+Clojureizer.h"
@@ -141,7 +142,7 @@ - (void)doClojureizer
return [NSNumber numberWithInt:([item intValue] * 2)];
}];
ExampleLog(@"[simpleArray map:#(* 2 %)", @"%@", results);
-
+
results = [simpleArray filter:^BOOL(id obj) {
return [obj intValue] >= 5;
}];
@@ -151,6 +152,13 @@ - (void)doClojureizer
return [obj intValue] >= 5;
}];
ExampleLog(@"[simpleArray remove:#(>= % 5)", @"%@", results);
+
+// NSArray *stringArray = [NSArray arrayWithObjects:
+// @"one",
+// @"two",
+// @"three", nil];
+// results = [[stringArray collect] stringByAppendingString:@"suffix"];
+// ExampleLog(@"(map %(stringByAppendingString % 'suffix') stringArray)", @"%@", results);
}
View
@@ -19,9 +19,11 @@ Assumptions:
What We'll Cover:
- The Basics
- Objective-C w/ source code
+ - Mention of ARC
- objects and classes
- An intro to C Structs, and how Objective-C uses them
- instances, classes, superclasses, & meta-classes
+ - Categories, this is how they work.
- Messaging
- Basics: methods, messages, selectors, message sending
- Sending Messages
@@ -36,12 +38,14 @@ What We'll Cover:
- Message forwarding examples
- Swizzling
- Method swizzling: swapping method implementations at runtime
- - ISA swizzling : changing classes at runtime
+ - ISA swizzling : changing classes at runtime
+ - This is how KVO works
- That's cool, but what do I do now?
Basics / Intro:
- Like C++, no multiple inheritance, no operator overloading
+- Now with ARC
- It all comes from libobjc, a collection of C functions
objc_msgSend --> [object message]
@@ -211,7 +215,10 @@ Sending Messages
- NSBundle
- Fast Forwarding
- forwardingTargetForSelector: useful for proxy objects, such as CacheProxy.h/m
- - See ch-20 CacheProxy.m/h
+ - See ch-20 CacheProxy.m/h (not an awesome example)
+ - The Higher Order Messaging (HOM) example is much more interesting
+ (more on this below)
+
- Normal Forwarding
- Slower, but more flexible
- Forwarding Failure w/ doesNotRecognizeSelector:
@@ -263,38 +270,48 @@ The Objective-C Runtime Programming Guide
- but, multiple inheritance combines capabilities in single object
- forwarding provides abilities in smaller objects, associated in transparent way to the message sender
- Implement "Array#map"
- - The Complete Friday Q&A p 104
-
- @interface ArrayMapProxyNormal : NSProxy
- {
- NSArray *_array;
- }
- - (id)initWithArray:(NSArray *)array;
- @end
+ - HOM Example: http://www.mikeash.com/pyblog/friday-qa-2009-04-24-code-generation-with-llvm-part-2-fast-objective-c-forwarding.html
+ - The Complete Friday Q&A p 104
+ - Super not-fun to implement, here's the simpler way...
+ (This is old code and doesn't work... look at this just to illustrate concept)
- @implementation ArrayMapProxyNormal
- - (id)initWithArray:(NSArray *)array
- {
- _array = array;
- return self;
- }
- - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
- {
- return [[_array lastObject] methodSignatureForSelector:sel];
- }
- - (void)forwardInvocation:(NSInvocation *)inv
- {
- NSMutableArray *newArray = [NSMutableArray array];
- for(id obj in _array)
+ @interface ArrayMapProxyNormal : NSProxy
+ {
+ NSArray *_array;
+ }
+ - (id)initWithArray:(NSArray *)array;
+ @end
+ @implementation ArrayMapProxyNormal
+ - (id)initWithArray:(NSArray *)array
+ {
+ _array = array;
+ return self;
+ }
+ - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
+ {
+ return [[_array lastObject] methodSignatureForSelector:sel];
+ }
+ - (void)forwardInvocation:(NSInvocation *)inv
{
- id retval;
- [inv invokeWithTarget:obj];
- [inv getReturnValue:&retval;];
- [newArray addObject:retval];
+ NSMutableArray *newArray = [NSMutableArray array];
+ for(id obj in _array)
+ {
+ id retval;
+ [inv invokeWithTarget:obj];
+ [inv getReturnValue:&retval;];
+ [newArray addObject:retval];
+ }
+ [inv setReturnValue:&newArray;];
}
- [inv setReturnValue:&newArray;];
- }
- @end
+ @end
+
+
+ OnNSArray Category:
+ - (id)mapNormal
+ {
+ return [[[ArrayMapProxyNormal alloc] initWithArray:self] autorelease];
+ }
+
@@ -305,7 +322,7 @@ Method Swizzling
- Allow you to change the behaviors of Apple frameworks
- Why not use a category?
- - Category meethod replaces original method, with no way to call original method
+ - Category method replaces original method, with no way to call original method
- Original method you wish to replace might have been implemented by category
- There is no way to determine which category method "wins"
- Option 1 (more bad): method_exhangeImplementations
@@ -384,13 +401,14 @@ Downsides to Swizzling
WHAT ABOUT...?
- KVO refresher
- Complete Friday Q&A V1: How Key-Value Observing Works
+ - KVO Done Right (Take 2): http://www.mikeash.com/pyblog/friday-qa-2012-03-02-key-value-observing-done-right-take-2.html
- Blocks
- Complete Friday Q&A V1:
- Practical Blocks
- Blocks in Objective-C
- Implement Clojure/Ruby collection methods with trampolining or blocks?
- - http://cocoadev.com/index.pl?HigherOrderMessaging
+- Higher order messaging: http://cocoadev.com/index.pl?HigherOrderMessaging
- Complete Friday Q&A V1: Fast Objective-C Forwarding
- implement HOM: map?

0 comments on commit 4b7b31c

Please sign in to comment.