{"id":447,"date":"2003-05-18T19:12:11","date_gmt":"2003-05-18T23:12:11","guid":{"rendered":"\/?p=447"},"modified":"2025-07-03T18:53:49","modified_gmt":"2025-07-03T22:53:49","slug":"mac_os_x_advanced_develop","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2003\/05\/18\/mac_os_x_advanced_develop\/","title":{"rendered":"Mac OS X Advanced Development Techniques"},"content":{"rendered":"<p>\n\n<a href=\"http:\/\/stevenf.com\/mt\/archives\/000301.php#000301\">Steven Frank<\/a> and <a href=\"http:\/\/www.scifihifi.com\/\">Buzz Andersen<\/a> like <a href=\"http:\/\/www.amazon.com\/exec\/obidos\/ASIN\/0672325268\/michaeltsai-20\">this new book<\/a> by Joe Zobkiw. I&rsquo;m not really a fan of it, though.\n\n<\/p>\n\n\n\n<p>\n\nThe book begins by repeating the <a href=\"http:\/\/www.raoli.com\/archives\/2003\/04\/000060.php\">annoying<\/a> assertion that &ldquo;The Cocoa application environment is the native Mac OS X development environment&rdquo; (page 14).\n\n<\/p>\n\n\n\n<p>\n\nPage 17 exhorts you to &ldquo;read Apple&rsquo;s Human Interface Guidelines and practice them,&rdquo; but on page 40 the book directs you to create a metal application that <a href=\"http:\/\/developer.apple.com\/techpubs\/macosx\/Essentials\/AquaHIGuidelines\/AHIGWindows\/chapter_5_section_4.html\">has no business<\/a> being metal, and page 61 includes a hideous example of <a href=\"http:\/\/developer.apple.com\/techpubs\/macosx\/Essentials\/AquaHIGuidelines\/AHIGLayout\/chapter_8_section_3.html\">excessive group boxes<\/a>.\n\n<\/p>\n\n\n\n<p>\n\nPage 22 demonstrates scalar accessor methods by&hellip;creating an infinite loop.\n\n<\/p>\n\n\n\n<p>\n\nPage 56 characterizes Cocoa&rsquo;s reference counting system as a &ldquo;big gotcha.&rdquo; It doesn&rsquo;t explain retaining and releasing particularly well, nor does it link to <a href=\"http:\/\/www.stepwise.com\/Articles\/Technical\/HoldMe.html\">more comprehensive coverage<\/a>.\n\n<\/p>\n\n\n\n<p>\n\nPage 63 uses the application controller&rsquo;s <code>+initialize<\/code> method to set the application&rsquo;s defaults if they have not already been set. It uses an integer where a boolean would be a better fit, and it creates <code>NSNumber<\/code> objects instead of just using <code>-setInteger:forKey:<\/code>. More seriously, the example probably should have used <code>-registerDefaults:<\/code> instead of actually setting the defaults.\n\n<\/p>\n\n\n\n<p>\n\nPage 73 says &ldquo;pop-up menu&rdquo; when it means &ldquo;contextual menu.&rdquo;\n\n<\/p>\n\n\n\n<p>\n\nIn a great example of the book&rsquo;s cursory coverage, page 126 recommends embedding frameworks in your application&rsquo;s bundle without mentioning that the key to doing this is to use the magic <tt>@executable_path\/..\/Frameworks<\/tt> string for the installation path. It merely tells you to use Project Builder&rsquo;s stationery, which is pre-configured for the framework being in the <tt>Library<\/tt> folder.\n\n<\/p>\n\n\n\n<p>\n\nPages 143 and 158&ndash;160 use <code>CFPreferences<\/code> (and other Core Foundation stuff) rather than <code>NSUserDefaults<\/code> (and other Cocoa stuff) in a Cocoa example without explaining why.\n\n<\/p>\n\n\n\n<p>\n\nPage 155 says to give your <tt>.prefPane<\/tt> package a custom icon by copying from the <tt>.icns<\/tt> file&rsquo;s Get Info window and pasting into the Get Info window of the <tt>.prefPane<\/tt>. First, this won&rsquo;t work. You want to copy the contents of the <tt>.icns<\/tt> file, not its icon. Second, you&rsquo;d have to re-do this process after each clean build. It would be better to use Project Builder to set the icon using the <tt>Info.plist<\/tt> file. Now, maybe there&rsquo;s some reason this doesn&rsquo;t work with <tt>.prefPane<\/tt>s, but if this is the case the book should say so.\n\n<\/p>\n\n\n\n<p>\n\nPage 163 says that status items &ldquo;are intended to display hardware or network status\/settings only. This is why you will see iChat and Airport[sic] but not Mail.app.&rdquo; Now there&rsquo;s a clear distinction.\n\n<\/p>\n\n\n\n<p>\n\nPage 169 creates a menu using <code>[[[NSMenu alloc] init] retain]<\/code> and only releases it once, thus leaking it.\n\n<\/p>\n\n\n\n<p>\n\nThe Threads chapter is basically an introduction to what threads are. It doesn&rsquo;t really talk about Cocoa thread-safety, and in fact the examples are thread-unsafe. Nor does it mention how to communicate between different threads.\n\n<\/p>\n\n\n\n<p>\n\nThe Terminal (<code>NSTask<\/code>) chapter doesn&rsquo;t really add anything beyond Apple&rsquo;s documentation and sample code. It doesn&rsquo;t discuss buffering issues, which are probably the biggest gotcha here. It&rsquo;s also not a good example to emulate: it uses polling, it doesn&rsquo;t protect a shared variable with locks, and it calls the AppKit from a child thread. For some unknown reason, all of the threads end with calls to <code>[NSThread exit]<\/code>, even though the book ascribes no benefit to this practice.\n\n<\/p>\n\n\n\n<p>\n\nThe XML-RPC chapter has some information that&rsquo;s not in other Mac books to my knowledge. However, it contains this confusing bit of code:\n\n<\/p>\n\n\n\n<pre>\n\n\/\/ Add the users choices to the dictionary to be passed as parameters\n\nparams = [NSMutableDictionary dictionaryWithCapacity:2];\n\n[params setObject:selectedProduct forKey:selectedProduct];\n\n[params setObject:selectedColor forKey:selectedColor];\n\n\n\n\/\/ Create the array to specify the order of the parameter values\n\nparamsOrder = [NSArray arrayWithObjects:selectedProduct, selectedColor, nil];\n\n<\/pre>\n\n\n\n<p>\n\nI would have made the keys and array elements string constants like <code>@\"ProductColor\"<\/code> and <code>@\"ProductProduct\"<\/code>. Not only does that make the intent clearer, but it won&rsquo;t fail if a color and a product have the same name.\n\n<\/p>\n\n\n\n<p>\n\nAnd the next page goes on to release <code>params<\/code> and <code>paramsOrder<\/code> both of which were already autoreleased. The subsequent SOAP chapter does use readable string keys, but it has the same over-releasing bug.\n\n<\/p>\n\n\n\n<p>\n\nPage 298 promises to help find &ldquo;Application Support Directories,&rdquo; but apparently the  &ldquo;Application Support&rdquo; folder isn&rsquo;t one of them. It would have been better to provide some alias-savvy code for locating and creating the application&rsquo;s folder in <tt>~\/Library\/Application Support<\/tt>.\n\n<\/p>\n\n\n\n<p>\n\nPage 300 uses <code>NSOKButton<\/code> instead of <code>NSAlertDefaultReturn<\/code>. Luckily, the constants have the same value so the code does work.\n\n<\/p>\n\n\n\n<p>\n\nPage 301 again over-retains an <code>NSMenu<\/code>.\n\n<\/p>\n\n\n\n<p>\n\nAlthough there are a lot of errors (and more typos) in this book, I sympathize. It&rsquo;s tough to get all the details right, and many technical books do no better. However, my larger concerns are the choice of topics and the depth of coverage.<\/p>\n\n\n\n<p>\n\nDon&rsquo;t let the title fool you. This is not an advanced book, nor is it about techniques. Instead, it&rsquo;s a guided tour through some example projects that are off the beaten path. Many of them are covered in other books and articles, but some are not. Thus, it&rsquo;s great that this book exists, but it will not be of interest to everyone. The advanced book I was <em>hoping<\/em> to find, would cover things like AppleScript, inter-thread communication and threaded application architectures, application code structure, databases and persistence, AppKit gotchas, third-party libraries and wrappers, medium- and lower-level networking, Quartz tricks, and optimization.\n\n<\/p>\n\n\n\n<p>\n\nThe book&rsquo;s coverage is wide and shallow. It&rsquo;s based around a series of examples, and it&rsquo;s wont to show a simple code example and then paraphrase the code in prose. As a result, in many cases I felt it didn&rsquo;t add much value over Apple&rsquo;s documentation and sample code. I would have liked to see less focus on <em>what<\/em> and more on <em>why<\/em>. Also, if a book is based around examples, I would expect them to exhibit best practice techniques. In contrast, Bill Cheeseman&rsquo;s <a href=\"http:\/\/www.amazon.com\/exec\/obidos\/ASIN\/0201878011\/michaeltsai-20\">Cocoa Recipes<\/a> manages to use an example-driven style without ignoring the rationales, subtleties, and gotchas.\n\n<\/p>\n\n\n\n<p>\n\n<a href=\"http:\/\/www.amazon.com\/exec\/obidos\/ASIN\/0672322307\/michaeltsai-20\">Cocoa Programming<\/a> by Anguish, Buck, and Yacktman is both wider and deeper than this book. Not only does it have great introductory material (for those who know how to program but don&rsquo;t know Cocoa), but it also contains a lot more advanced information. Every Cocoa programmer should own this book. Its only significant flaw is ignoring AppleScript&mdash;as do all the other Cocoa books I&rsquo;ve seen.\n\n<\/p>\n\n\n\n<p>\n\n<cite>Mac OS X Advanced Development Techniques<\/cite> does contain chapters on <a href=\"http:\/\/developer.apple.com\/techpubs\/macosx\/ReleaseNotes\/CFBundleAndCFPlugIn.html\">Carbon<\/a> and <a href=\"file:\/\/\/Developer\/Documentation\/Cocoa\/TasksAndConcepts\/ProgrammingTopics\/LoadingResources\/index.html\">Cocoa<\/a> plug-ins and on <a href=\"http:\/\/developer.apple.com\/techpubs\/macosx\/Networking\/WebServices\/\">XML-RPC and SOAP<\/a>. I don&rsquo;t know of other books that cover these, but Apple (see preceding links) and <a href=\"http:\/\/www.macdevcenter.com\/pub\/a\/mac\/2002\/10\/15\/cocoa.html\">O&rsquo;Reilly<\/a> have already done a decent job.\n\n<\/p>\n\n\n\n<p>\n\nI hope someone will step in and write a truly advanced book about Mac OS X programming. Until then, I recommend <a href=\"http:\/\/lists.apple.com\/mailman\/listinfo\">Apple<\/a> and <a href=\"http:\/\/www.omnigroup.com\/developer\/mailinglists\/\">Omni<\/a>&rsquo;s mailing lists, <a href=\"http:\/\/www.mulle-kybernetik.com\/artikel\/Optimization\/\">Mulle kybernetiK<\/a>,\n\n<a href=\"http:\/\/www.macdevcenter.com\/\">O&rsquo;Reilly<\/a>, <a href=\"http:\/\/www.stepwise.com\/Articles\/\">Stepwise<\/a>, and developer blogs.\n\n<\/p>","protected":false},"excerpt":{"rendered":"<p>Steven Frank and Buzz Andersen like this new book by Joe Zobkiw. I&rsquo;m not really a fan of it, though. The book begins by repeating the annoying assertion that &ldquo;The Cocoa application environment is the native Mac OS X development environment&rdquo; (page 14). Page 17 exhorts you to &ldquo;read Apple&rsquo;s Human Interface Guidelines and practice [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2025-07-03T22:53:13Z","apple_news_api_id":"2f58b917-5c10-4496-86eb-57a889ec4979","apple_news_api_modified_at":"2025-07-03T22:53:51Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAQ==","apple_news_api_share_url":"https:\/\/apple.news\/AL1i5F1wQRJaG61eoiexJeQ","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[2786,63,71],"class_list":["post-447","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-aliases","tag-book","tag-programming"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/447","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=447"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/447\/revisions"}],"predecessor-version":[{"id":48332,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/447\/revisions\/48332"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=447"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=447"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=447"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}