{"id":78,"date":"2012-10-16T23:20:29","date_gmt":"2012-10-17T03:20:29","guid":{"rendered":"http:\/\/blog.blackgecko.com\/?p=78"},"modified":"2012-10-17T09:32:45","modified_gmt":"2012-10-17T13:32:45","slug":"categories-associative-references-powerful-stuff","status":"publish","type":"post","link":"http:\/\/blog.blackgecko.com\/?p=78","title":{"rendered":"Associative References"},"content":{"rendered":"<p>If you&#8217;ve been developing with Objective-C for a while you know it&#8217;s powerful stuff. While it&#8217;s not as elegant looking as some languages, such as Ruby, it does have a rather impressive array of features that make it just flexible as new languages, such as Ruby.<\/p>\n<p>One of the flexible features of Objective-C is Categories.\u00a0Categories allow developers to snap on methods to classes they didn&#8217;t create and don&#8217;t have access to their source code. Beyond that, these methods become part of the class hierarchy.<\/p>\n<p>One complaint that I&#8217;ve had with Categories is that you can&#8217;t add properties as part of the category snap on. Recently I wanted to extend UITextView so that it would be easier to take advantage of AttributesStrings. My first thought was to create a Category and initially it seemed I was on the right track. That was, until I realized that I wanted to have the UITextView keep track of default fonts. Default fonts mean properties and properties mean so long Category &#8230; or does it?<\/p>\n<p>After building a subclass of UITextView, to do the things I want AND adding new properties, I wasn&#8217;t happy with the way thing looked. It&#8217;s not that the code wouldn&#8217;t do it&#8217;s job but it just didn&#8217;t feel as clean as it could be. I tried to improve my code by splitting off some capability into a Category.<\/p>\n<p>As I wrote the Category it just felt right so I started trying to move the rest of my code into the category but still there were these properties. A little research on the net turned over something new, <a title=\"Associative References\" href=\"http:\/\/developer.apple.com\/library\/ios\/#documentation\/cocoa\/conceptual\/objectivec\/chapters\/ocAssociativeReferences.html\">Associative References<\/a>.<\/p>\n<p>Associative References make it possible, like Categories, to attach (or associate) an\u00a0object instance variables to an existing class and as the French would say &#8220;et voila&#8221; there you go, Categories with Properties.<\/p>\n<p>Ok, so how do you make use of Associative References? First stop is to add properties to your Category:<\/p>\n<pre class=\"brush: objc; title: ; notranslate\" title=\"\">\r\n@interface UITextView (Utilities)\r\n\r\n@property (nonatomic, strong) UIFont *regularFont;\r\n<\/pre>\n<p>Now, Xcode will complain that since this is a category you&#8217;re going to have to implement the getter and setter for this property. So let&#8217;s get to implementing:<\/p>\n<pre class=\"brush: objc; title: ; notranslate\" title=\"\">\r\n#import &lt;objc\/runtime.h&gt;\r\n\r\nstatic void *RegularFontKey;\r\n\r\n@implementation UITextView (Utilities)\r\n\r\n- (UIFont *)regularFont{\r\n    return objc_getAssociatedObject(self, &amp;RegularFontKey);\r\n}\r\n\r\n- (void)setRegularFont:(UIFont *)regularFont{\r\n    objc_setAssociatedObject(self, &amp;RegularFontKey, regularFont, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\r\n}\r\n<\/pre>\n<p>Lines 7-9 and 11-13 are the methods that addresses Xcodes complaint. Pretty boiler plate. The magic happens on lines 8 and 12. Line 12 sets the value of the property and line 8 gets the value of the property. In both cases you&#8217;ll notice the use of the void pointer from line 3. This is a key that makes the association possible and it needs to be unique per property \u00a0and per class but not per property. This means that a developer simply has to replicate the pattern in line 3 per key.<\/p>\n<p>In general, I would say simply replicate the\u00a0pattern laid out in the code above to add properties to a category.<\/p>\n<p>Happy Hunting<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;ve been developing with Objective-C for a while you know it&#8217;s powerful stuff. While it&#8217;s not as elegant looking as some languages, such as Ruby, it does have a rather impressive array of features that make it just flexible &hellip; <a href=\"http:\/\/blog.blackgecko.com\/?p=78\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,11,6,8],"tags":[],"class_list":["post-78","post","type-post","status-publish","format-standard","hentry","category-clang","category-ios","category-objective-c","category-programming"],"_links":{"self":[{"href":"http:\/\/blog.blackgecko.com\/index.php?rest_route=\/wp\/v2\/posts\/78","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.blackgecko.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.blackgecko.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.blackgecko.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.blackgecko.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=78"}],"version-history":[{"count":5,"href":"http:\/\/blog.blackgecko.com\/index.php?rest_route=\/wp\/v2\/posts\/78\/revisions"}],"predecessor-version":[{"id":83,"href":"http:\/\/blog.blackgecko.com\/index.php?rest_route=\/wp\/v2\/posts\/78\/revisions\/83"}],"wp:attachment":[{"href":"http:\/\/blog.blackgecko.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=78"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.blackgecko.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=78"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.blackgecko.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=78"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}