Blocks/Closures
Blocks are another way that Objective C performs callbacks. Flash and Swift uses this technique as well, where they are called closures. Basically this involves passing in a function/method/message to the child, whilst maintaining the focus of the parent. So it would be a method that the child can call, and local variables within the closure are based on local variables where the closure is defined. I find it makes your code hard to read, (especially in Objective C where the syntax can be a struggle to get right too!) but it’s still a valid technique.
One caveat – ‘this’ in an ActionScript closure is actually assumed to be in the global scope.
ActionScript3:
Parent.as (Document class)
package { import flash.display.MovieClip; public class Parent extends MovieClip { private var string:String; public function Parent() { string="I am Parent"; // function closure var parentMethod:Function=function():String { return(string); } var child:Child=new Child(); child.runThis(parentMethod); } } }
Child.as
package { public class Child { private var string:String; public function Child() { string="I am Child"; } public function runThis(functionToRun:Function):void { functionToRun(); } } } //traces I am Parent
Objective C:
In Parent.m
NSString *string = @"I am Parent"; NSString * (^parentMethod)() = ^ NSString * () { return string; }; Child *child = [[Child alloc] init]; NSLog(@"%@", [child runThis:parentMethod]);
In Child.m
-(NSString *)runThis:(NSString *(^)())blockToRun { NSString *string = @"I am Child"; return(blockToRun()); } //NSLogs I am Parent
Swift:
The following works well in playgrounds:
import Cocoa var parent:Parent=Parent() parent.go() //Note that this outputs I am Parent class Parent { var string="I am Parent" var child = Child() func parentMethod()->NSString { return string } func go()->NSString { return child.runThis(parentMethod) } } class Child { var string="I am Child" func runThis(closure: () -> NSString)->NSString { return closure() } }
[…] Part 4: Blocks/Closures […]