{"id":320,"date":"2007-04-12T14:20:23","date_gmt":"2007-04-12T21:20:23","guid":{"rendered":"http:\/\/www.red-sweater.com\/blog\/320\/abusing-objective-c-with-class"},"modified":"2007-04-12T14:47:33","modified_gmt":"2007-04-12T21:47:33","slug":"abusing-objective-c-with-class","status":"publish","type":"post","link":"https:\/\/redsweater.com\/blog\/320\/abusing-objective-c-with-class","title":{"rendered":"Abusing Objective C With Class"},"content":{"rendered":"<p>Dynamic messaging is one of the nifty features of Cocoa and Objective-C programming on the Mac. You don&#8217;t have to know which class, or even which method your code will call until runtime. The feature is utilized a great deal by the delegation pattern employed by most standard classes in AppKit. For instance, when a window is threatening to close, Apple yields the final decision making to a delegate method, if present:<\/p>\n<p><pre style=\"font-size:1.0em;\">\n<code>\n- (BOOL) windowShouldClose:(id)sender;\n<\/code>\n<\/pre>\n<\/p>\n<p>\nIf you implement this delegate method and return NO for a particular window, then the user&#8217;s attempts to close it are thwarted (hopefully because you just did something friendly like ask them if they were sure or not).\n<\/p>\n<p>\nIf we&#8217;re agreed that delegation and dynamic messaging are a good idea, we should be prepared to use them in our own code as well. Let&#8217;s say we&#8217;re writing a custom class where delegation of this kind would be useful. We&#8217;d like to be as much like Apple as possible, to further solidify the patterns that we all use on a regular basis.\n<\/p>\n<p>\nMy example application is a coffee maker, and it makes coffee at regular intervals unless the delegate method believes it should not:\n<\/p>\n<p><pre style=\"font-size:1.0em;\">\n<code>\n- (BOOL) coffeeMaker:(RSCoffeeMaker*)theMaker\n\tshouldBrewForScheduledDate:(NSDate*)scheduledDate;\n<\/code>\n<\/pre>\n<\/p>\n<p>\nWhat must the code in the coffee maker do in order to satisfy this contract? The &#8220;scheduledBrewTimerFired:&#8221; method might look something like this:\n<\/p>\n<p><pre style=\"font-size:1.0em;\">\n<code>\n- (void) scheduledBrewTimerFired:(NSTimer*)brewTimer\n{\n\tBOOL shouldBrew = YES;\n\t\n\t\/\/ Give the delegate a chance to reject\n\tSEL delSelector = \n\t\t@selector(coffeeMaker:shouldBrewForScheduledDate:);\n\n\tif ((mDelegate != nil) &&\n\t\t([mDelegate respondsToSelector:delSelector] == YES))\n\t{\n\t\tshouldBrew = [mDelegate performSelector:delSelector\n\t\t\twithObject:self\n\t\t\twithObject:[brewTimer fireDate]];\n\t}\n\t\n\tif (shouldBrew == YES)\n\t{\n\t\t\/\/...\n\t}\n}\n<\/code>\n<\/pre>\n<\/p>\n<p>\nNifty, right? Yes, nifty. But wrong. What&#8217;s the problem? It&#8217;s that line where performSelector is called. If you have as many warnings turned on as you should, you&#8217;ll see something along the lines of &#8220;<em>warning: assignment makes integer from pointer without a cast<\/em>.&#8221; The reason? The performSelector method returns an &#8220;id&#8221;, not a &#8220;BOOL&#8221;. We&#8217;re expecting magic to happen here, and those of us who grew comfortable with the nuances of PowerPC-based calling conventions have seen magic happen here more often than is healthy.\n<\/p>\n<p>\nBy violating the function prototype for performSelector, we&#8217;re robbing the compiler of its ability to accurately produce assembly code that retrieves the BOOL return type correctly. That means we&#8217;ll get the wrong answer some percentage of the time, where that percentage is determined by the degree to which <em>BOOL<\/em> and <em>id<\/em> return types are handled differently on the platform.\n<\/p>\n<p>\nMy first instinct in addressing this problem was to go down a layer. Surely if performSelector is using an unsatisfactory prototype, I could just drop down to objc_msgSend and handle the messaging myself. But alas! The lower-level function <em>also<\/em> returns an id. At this level, there are some special functions such as objc_msgSend_stret, which messages an object and returns a <em>structure<\/em>, but there isn&#8217;t a handy objc_msgSend_boolret for our convenience.\n<\/p>\n<p>\nSo what&#8217;s a conscientous developer to do? I was lucky to discover a <a href=\"http:\/\/www.cocoabuilder.com\/archive\/message\/cocoa\/2006\/2\/12\/156604\">mailing-list thread<\/a>, in which the answer to this question was beautifully outlined by Greg Parker of Apple. Credit also goes to Rosyna of Unsanity, for asking the question that led to Greg&#8217;s answer. Rosyna later expressed appreciation in a <a href=\"http:\/\/www.unsanity.org\/archives\/haxies\/universally_fat_1.php\">follow-up post<\/a>.\n<\/p>\n<p>\nSo what&#8217;s the trick? In order to get the freedom of dynamic messaging combined with the complete cooperation of the compiler, we need to define a custom function pointer. This points to the same address in memory as the objc_msgSend function, but is defined with a differing prototype. This way we get the message delivery functionality of the Objective-C runtime, while letting the compiler in on the fact that the method being messaged will in fact return a BOOL typed response.\n<\/p>\n<p><pre style=\"font-size:1.0em;\">\n<code>\n#import &lt;objc\/objc-runtime.h>\n\n- (void) scheduledBrewTimerFired:(NSTimer*)brewTimer\n{\n\tbool shouldBrew = YES;\n\t\n\t\/\/ Give the delegate a chance to reject\n\tSEL delSelector = \n\t\t@selector(coffeeMaker:shouldBrewForScheduledDate:);\n\tif ((mDelegate != nil) &&\n\t\t([mDelegate respondsToSelector:delSelector] == YES))\n\t{\n\t\t\/\/ Give the compiler a clue - courtesy of Greg Parker\n\t\tBOOL (*MyMagicSender)(id, SEL, id, id) = \n\t\t\t(BOOL (*)(id, SEL, id, id)) objc_msgSend;\n\n\t\tshouldBrew = MyMagicSender(mDelegate, delSelector,\n\t\t\tself, [brewTimer fireDate]);\n\t}\n\t\n\tif (shouldBrew == YES)\n\t{\n\t\t\/\/...\n\t}\n}\n<\/code>\n<\/pre>\n<\/p>\n<p>\nNifty, right? And correct, too. Enjoy!\n<\/p>\n<p>\n<strong>Update:<\/strong> <a href=\"http:\/\/www.noodlesoft.com\/blog\/\">Paul Kim<\/a> via chat, and Jan Van Boghout in the comments below each noticed a flaw in my contrived example. Since I already know the selector I&#8217;m planning to call, I could just define it explicitly with a regular Objective-C method prototype. Then the compiler would know exactly how to generate the code if I called the delegate directly:<\/p>\n<pre>\n<code>\nshouldBrew = [mDelegate coffeeMaker:self\n\tshouldBrewForScheduledDate:[brewTimer fireDate]];\n<\/code><\/pre>\n<\/p>\n<p>\nThat&#8217;s true, and it&#8217;s a fault in my overly-contrived example. But imagine a more dynamic scenario, where the prototype of the method is known, but not the selector. For instance, if the class offers clients the ability to specify a selector:<\/p>\n<pre>\n<code>\n- (void) scheduleBrewingAtDate:(NSDate*)brewDate\n\twithBrewDelegate:(id)brewDelegate\n\twithDelegateSelector:(SEL)delSel;\n<\/code>\n<\/pre><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dynamic messaging is one of the nifty features of Cocoa and Objective-C programming on the Mac. You don&#8217;t have to know which class, or even which method your code will call until runtime. The feature is utilized a great deal by the delegation pattern employed by most standard classes in AppKit. For instance, when a [&hellip;]<\/p>\n","protected":false},"author":10,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,11,15,5],"tags":[],"class_list":["post-320","post","type-post","status-publish","format-standard","hentry","category-apple","category-cocoa","category-programming","category-xcode"],"_links":{"self":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/320","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/comments?post=320"}],"version-history":[{"count":0,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/320\/revisions"}],"wp:attachment":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/media?parent=320"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/categories?post=320"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/tags?post=320"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}