{"id":3572,"date":"2010-05-26T14:39:03","date_gmt":"2010-05-26T19:39:03","guid":{"rendered":"http:\/\/bobbeaty.com\/wp\/?p=3572"},"modified":"2010-11-30T09:05:34","modified_gmt":"2010-11-30T15:05:34","slug":"do-not-autorelease-the-return-from-copywithzone","status":"publish","type":"post","link":"https:\/\/bobbeaty.com\/wp\/archives\/3572","title":{"rendered":"Do Not <tt>autorelease<\/tt> the Return from <tt>-copyWithZone:<\/tt>"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bobbeaty.com\/wp\/wp-content\/uploads\/2007\/09\/xcode.jpg\" alt=\"xcode.jpg\" title=\"xcode.jpg\" border=\"0\" width=\"128\" height=\"128\" style=\"margin-left:10px; float:right;\" \/><\/p>\n<p>This afternoon I was working on my latest version of the CryptoQuip solver and decided to turn on the built-in Clang Static Analyzer for all my debug builds as I've gotten to the point that I'm really getting close to having something useful to look at. Interestingly enough, it pointed out a problem on <strong><em>all<\/em><\/strong> my implementations of <tt>-copyWithZone:<\/tt> - I was returning an <tt>autorelease<\/tt>d instance and that's not the intended signature of the <tt>-copyWithZone:<\/tt> method.<\/p>\n<p>For example, my original code for a simple object was:<\/p>\n<pre class=\"objc\" style=\"font-family:monospace;\">  <span style=\"color: #11740a; font-style: italic;\">\/*!\n   This is the standard copy method for the Legend so that we can make\n   clean copies without having to worry about all the details. It's a nice\n   deep copy, where the contents of the returned Legend are the same as\n   this instance's.\n   *\/<\/span>\n  <span style=\"color: #002200;\">-<\/span> <span style=\"color: #002200;\">&#40;<\/span><span style=\"color: #a61390;\">id<\/span><span style=\"color: #002200;\">&#41;<\/span> copyWithZone<span style=\"color: #002200;\">:<\/span><span style=\"color: #002200;\">&#40;<\/span><span style=\"color: #a61390;\">NSZone<\/span><span style=\"color: #002200;\">*<\/span><span style=\"color: #002200;\">&#41;<\/span>zone\n  <span style=\"color: #002200;\">&#123;<\/span>\n    <span style=\"color: #11740a; font-style: italic;\">\/\/ simply use the allocWithZone and populate it properly - easy<\/span>\n    <span style=\"color: #a61390;\">return<\/span> <span style=\"color: #002200;\">&#91;<\/span><span style=\"color: #002200;\">&#91;<\/span><span style=\"color: #002200;\">&#91;<\/span>Legend allocWithZone<span style=\"color: #002200;\">:<\/span>zone<span style=\"color: #002200;\">&#93;<\/span> initWithMap<span style=\"color: #002200;\">:<\/span><span style=\"color: #002200;\">&#91;<\/span>self getMap<span style=\"color: #002200;\">&#93;<\/span><span style=\"color: #002200;\">&#93;<\/span> autorelease<span style=\"color: #002200;\">&#93;<\/span>;\n  <span style=\"color: #002200;\">&#125;<\/span><\/pre>\n<p>and the Static Analyzer pointed out that the retain count of +0 was wrong and it was supposed to be +1. I simply changed it to read:<\/p>\n<pre class=\"objc\" style=\"font-family:monospace;\">  <span style=\"color: #11740a; font-style: italic;\">\/*!\n   This is the standard copy method for the Legend so that we can make\n   clean copies without having to worry about all the details. It's a nice\n   deep copy, where the contents of the returned Legend are the same as\n   this instance's.\n   *\/<\/span>\n  <span style=\"color: #002200;\">-<\/span> <span style=\"color: #002200;\">&#40;<\/span><span style=\"color: #a61390;\">id<\/span><span style=\"color: #002200;\">&#41;<\/span> copyWithZone<span style=\"color: #002200;\">:<\/span><span style=\"color: #002200;\">&#40;<\/span><span style=\"color: #a61390;\">NSZone<\/span><span style=\"color: #002200;\">*<\/span><span style=\"color: #002200;\">&#41;<\/span>zone\n  <span style=\"color: #002200;\">&#123;<\/span>\n    <span style=\"color: #11740a; font-style: italic;\">\/\/ simply use the allocWithZone and populate it properly - easy<\/span>\n    <span style=\"color: #a61390;\">return<\/span> <span style=\"color: #002200;\">&#91;<\/span><span style=\"color: #002200;\">&#91;<\/span>Legend allocWithZone<span style=\"color: #002200;\">:<\/span>zone<span style=\"color: #002200;\">&#93;<\/span> initWithMap<span style=\"color: #002200;\">:<\/span><span style=\"color: #002200;\">&#91;<\/span>self getMap<span style=\"color: #002200;\">&#93;<\/span><span style=\"color: #002200;\">&#93;<\/span>;\n  <span style=\"color: #002200;\">&#125;<\/span><\/pre>\n<p>and it's all fixed. But when I'm dealing with a little more complex objects, and I'm making a deep copy, I have to be careful and <tt>autorelease<\/tt> the copies I'm making because the setters are calling <tt>retain<\/tt> on the arguments, and I don't want to have a leak by leaving a copy with a retain count of +2.<\/p>\n<p>So a more complex version of <tt>-copyWithZone:<\/tt> looks like:<\/p>\n<pre class=\"objc\" style=\"font-family:monospace;\">  <span style=\"color: #11740a; font-style: italic;\">\/*!\n   This is the standard copy method for the Quip so that we can make\n   clean copies without having to worry about all the details. It's a nice\n   deep copy, where the contents of the returned Quip are the same as\n   this instance's.\n   *\/<\/span>\n  <span style=\"color: #002200;\">-<\/span> <span style=\"color: #002200;\">&#40;<\/span><span style=\"color: #a61390;\">id<\/span><span style=\"color: #002200;\">&#41;<\/span> copyWithZone<span style=\"color: #002200;\">:<\/span><span style=\"color: #002200;\">&#40;<\/span><span style=\"color: #a61390;\">NSZone<\/span><span style=\"color: #002200;\">*<\/span><span style=\"color: #002200;\">&#41;<\/span>zone\n  <span style=\"color: #002200;\">&#123;<\/span>\n    <span style=\"color: #11740a; font-style: italic;\">\/\/ simply use the allocWithZone and populate it properly - easy<\/span>\n    <span style=\"color: #a61390;\">id<\/span>   dup <span style=\"color: #002200;\">=<\/span> <span style=\"color: #002200;\">&#91;<\/span><span style=\"color: #002200;\">&#91;<\/span>Quip allocWithZone<span style=\"color: #002200;\">:<\/span>zone<span style=\"color: #002200;\">&#93;<\/span> init<span style=\"color: #002200;\">&#93;<\/span>;\n    <span style=\"color: #11740a; font-style: italic;\">\/\/ now let's add in copies of all the ivars we have to make it equal<\/span>\n    <span style=\"color: #002200;\">&#91;<\/span>dup setCypherText<span style=\"color: #002200;\">:<\/span><span style=\"color: #002200;\">&#91;<\/span><span style=\"color: #002200;\">&#91;<\/span><span style=\"color: #002200;\">&#91;<\/span>self getCypherText<span style=\"color: #002200;\">&#93;<\/span> copyWithZone<span style=\"color: #002200;\">:<\/span>zone<span style=\"color: #002200;\">&#93;<\/span> autorelease<span style=\"color: #002200;\">&#93;<\/span><span style=\"color: #002200;\">&#93;<\/span>;\n    <span style=\"color: #002200;\">&#91;<\/span>dup setStartingLegend<span style=\"color: #002200;\">:<\/span><span style=\"color: #002200;\">&#91;<\/span><span style=\"color: #002200;\">&#91;<\/span><span style=\"color: #002200;\">&#91;<\/span>self getStartingLegend<span style=\"color: #002200;\">&#93;<\/span> copyWithZone<span style=\"color: #002200;\">:<\/span>zone<span style=\"color: #002200;\">&#93;<\/span>\n                            autorelease<span style=\"color: #002200;\">&#93;<\/span><span style=\"color: #002200;\">&#93;<\/span>;\n    <span style=\"color: #a61390;\">for<\/span> <span style=\"color: #002200;\">&#40;<\/span>PuzzlePiece<span style=\"color: #002200;\">*<\/span> pp <span style=\"color: #a61390;\">in<\/span> <span style=\"color: #002200;\">&#91;<\/span>self getPuzzlePieces<span style=\"color: #002200;\">&#93;<\/span><span style=\"color: #002200;\">&#41;<\/span> <span style=\"color: #002200;\">&#123;<\/span>\n      <span style=\"color: #002200;\">&#91;<\/span><span style=\"color: #002200;\">&#91;<\/span>dup getPuzzlePieces<span style=\"color: #002200;\">&#93;<\/span> addObject<span style=\"color: #002200;\">:<\/span><span style=\"color: #002200;\">&#91;<\/span><span style=\"color: #002200;\">&#91;<\/span>pp copyWithZone<span style=\"color: #002200;\">:<\/span>zone<span style=\"color: #002200;\">&#93;<\/span> autorelease<span style=\"color: #002200;\">&#93;<\/span><span style=\"color: #002200;\">&#93;<\/span>;\n    <span style=\"color: #002200;\">&#125;<\/span>\n    <span style=\"color: #a61390;\">return<\/span> dup;\t\n  <span style=\"color: #002200;\">&#125;<\/span><\/pre>\n<p>where the arguments to the setters are calls to the instance's <tt>-copyWithZone:<\/tt> but to get the retain count correct, we need to <tt>autorelease<\/tt> them leaving them with a count of +0, to then have <tt>retain<\/tt> called on them by the setter.<\/p>\n<p>The NSMutableArray calls <tt>retain<\/tt> on all objects that are added to it, and <tt>release<\/tt> when they are removed. That explains the call to <tt>autorelease<\/tt> on the copy of the individual elements in that deep copy loop.<\/p>\n<p>In general, the Static Analyzer is saving my bacon by avoiding improper code practices as I get back into ObjC coding. I'm really happy with it. Fantastic!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This afternoon I was working on my latest version of the CryptoQuip solver and decided to turn on the built-in Clang Static Analyzer for all my debug builds as I&#8217;ve gotten to the point that I&#8217;m really getting close to having something useful to look at. Interestingly enough, it pointed out a problem on all [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,3],"tags":[],"class_list":["post-3572","post","type-post","status-publish","format-standard","hentry","category-cocoa-coding","category-coding"],"_links":{"self":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/3572","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/comments?post=3572"}],"version-history":[{"count":5,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/3572\/revisions"}],"predecessor-version":[{"id":4378,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/3572\/revisions\/4378"}],"wp:attachment":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/media?parent=3572"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/categories?post=3572"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/tags?post=3572"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}