From 94b21a1765ef7adfd0a8809d57645e4d32e46420 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko <gribozavr@gmail.com> Date: Thu, 13 Dec 2012 16:04:37 +0000 Subject: [PATCH] Documentation: convert AutomaticReferenceCounting.html to reST Patch by Anastasi Voitova with with small fixes by me. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@170132 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/AutomaticReferenceCounting.html | 2226 -------------------------- docs/AutomaticReferenceCounting.rst | 2061 ++++++++++++++++++++++++ 2 files changed, 2061 insertions(+), 2226 deletions(-) delete mode 100644 docs/AutomaticReferenceCounting.html create mode 100644 docs/AutomaticReferenceCounting.rst diff --git a/docs/AutomaticReferenceCounting.html b/docs/AutomaticReferenceCounting.html deleted file mode 100644 index 5354f8af346..00000000000 --- a/docs/AutomaticReferenceCounting.html +++ /dev/null @@ -1,2226 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<html> -<head> -<title>Objective-C Automatic Reference Counting (ARC)</title> -<link type="text/css" rel="stylesheet" href="../menu.css"> -<link type="text/css" rel="stylesheet" href="../content.css"> -<style type="text/css"> -/* Collapse the items in the ToC to the left. */ -div#toc ul { - padding-left: 0 -} - -/* Rationales appear in italic. */ -div.rationale { - font-style: italic -} - -div.rationale em { - font-style: normal -} - -/* Revisions are also italicized. */ -span.revision { - font-style: italic -} - -span.whenRevised { - font-weight: bold; - font-style: normal -} - -div h1 { font-size: 2em; margin: .67em 0 } -div div h1 { font-size: 1.5em; margin: .75em 0 } -div div div h1 { font-size: 1.17em; margin: .83em 0 } -div div div div h1 { margin: 1.12em 0 } - -span.term { font-style: italic; font-weight: bold } -</style> - -<script type="text/javascript"> -/// A little script to recursively build a table of contents. -function buildTOC(div, toc, ancestry) { - var children = div.childNodes; - var len = children.length; - - var childNumber = 0; - - var list = null; - for (var i = 0; i < len; ++i) { - var child = children[i]; - if (child.nodeName != "DIV") continue; - if (child.getAttribute("class") == "rationale") continue; - if (child.id == "toc") continue; - - // Okay, we're actually going to build a list node. - if (list === null) list = document.createElement("ul"); - - var childAncestry = ancestry + ++childNumber + "."; - - var headerNode = child.childNodes[1]; - var title = headerNode.innerHTML; - headerNode.insertBefore(document.createTextNode(childAncestry + " "), - headerNode.firstChild); - - var item = document.createElement("li"); - item.appendChild(document.createTextNode(childAncestry + " ")); - - var anchor = document.createElement("a"); - anchor.href = "#" + child.id; - anchor.innerHTML = title; - item.appendChild(anchor); - - buildTOC(child, item, childAncestry); - - list.appendChild(item); - } - if (list) toc.appendChild(list); -} - -function onLoad() { - var toc = document.getElementById("toc"); - var content = document.getElementById("content"); - buildTOC(content, toc, ""); -} -window.onload = onLoad; - -</script> -</head> -<body> - -<!--#include virtual="../menu.html.incl"--> - -<div id="content"> -<h1>Automatic Reference Counting</h1> - -<div id="toc"> -</div> - -<div id="meta"> -<h1>About this document</h1> - -<div id="meta.purpose"> -<h1>Purpose</h1> - -<p>The first and primary purpose of this document is to serve as a -complete technical specification of Automatic Reference Counting. -Given a core Objective-C compiler and runtime, it should be possible -to write a compiler and runtime which implements these new -semantics.</p> - -<p>The secondary purpose is to act as a rationale for why ARC was -designed in this way. This should remain tightly focused on the -technical design and should not stray into marketing speculation.</p> - -</div> <!-- meta.purpose --> - -<div id="meta.background"> -<h1>Background</h1> - -<p>This document assumes a basic familiarity with C.</p> - -<p><span class="term">Blocks</span> are a C language extension for -creating anonymous functions. Users interact with and transfer block -objects using <span class="term">block pointers</span>, which are -represented like a normal pointer. A block may capture values from -local variables; when this occurs, memory must be dynamically -allocated. The initial allocation is done on the stack, but the -runtime provides a <tt>Block_copy</tt> function which, given a block -pointer, either copies the underlying block object to the heap, -setting its reference count to 1 and returning the new block pointer, -or (if the block object is already on the heap) increases its -reference count by 1. The paired function is <tt>Block_release</tt>, -which decreases the reference count by 1 and destroys the object if -the count reaches zero and is on the heap.</p> - -<p>Objective-C is a set of language extensions, significant enough to -be considered a different language. It is a strict superset of C. -The extensions can also be imposed on C++, producing a language called -Objective-C++. The primary feature is a single-inheritance object -system; we briefly describe the modern dialect.</p> - -<p>Objective-C defines a new type kind, collectively called -the <span class="term">object pointer types</span>. This kind has two -notable builtin members, <tt>id</tt> and <tt>Class</tt>; <tt>id</tt> -is the final supertype of all object pointers. The validity of -conversions between object pointer types is not checked at runtime. -Users may define <span class="term">classes</span>; each class is a -type, and the pointer to that type is an object pointer type. A class -may have a superclass; its pointer type is a subtype of its -superclass's pointer type. A class has a set -of <span class="term">ivars</span>, fields which appear on all -instances of that class. For every class <i>T</i> there's an -associated metaclass; it has no fields, its superclass is the -metaclass of <i>T</i>'s superclass, and its metaclass is a global -class. Every class has a global object whose class is the -class's metaclass; metaclasses have no associated type, so pointers to -this object have type <tt>Class</tt>.</p> - -<p>A class declaration (<tt>@interface</tt>) declares a set -of <span class="term">methods</span>. A method has a return type, a -list of argument types, and a <span class="term">selector</span>: a -name like <tt>foo:bar:baz:</tt>, where the number of colons -corresponds to the number of formal arguments. A method may be an -instance method, in which case it can be invoked on objects of the -class, or a class method, in which case it can be invoked on objects -of the metaclass. A method may be invoked by providing an object -(called the <span class="term">receiver</span>) and a list of formal -arguments interspersed with the selector, like so:</p> - -<pre>[receiver foo: fooArg bar: barArg baz: bazArg]</pre> - -<p>This looks in the dynamic class of the receiver for a method with -this name, then in that class's superclass, etc., until it finds -something it can execute. The receiver <q>expression</q> may also be -the name of a class, in which case the actual receiver is the class -object for that class, or (within method definitions) it may -be <tt>super</tt>, in which case the lookup algorithm starts with the -static superclass instead of the dynamic class. The actual methods -dynamically found in a class are not those declared in the -<tt>@interface</tt>, but those defined in a separate -<tt>@implementation</tt> declaration; however, when compiling a -call, typechecking is done based on the methods declared in the -<tt>@interface</tt>.</p> - -<p>Method declarations may also be grouped into -<span class="term">protocols</span>, which are not inherently -associated with any class, but which classes may claim to follow. -Object pointer types may be qualified with additional protocols that -the object is known to support.</p> - -<p><span class="term">Class extensions</span> are collections of ivars -and methods, designed to allow a class's <tt>@interface</tt> to be -split across multiple files; however, there is still a primary -implementation file which must see the <tt>@interface</tt>s of all -class extensions. -<span class="term">Categories</span> allow methods (but not ivars) to -be declared <i>post hoc</i> on an arbitrary class; the methods in the -category's <tt>@implementation</tt> will be dynamically added to that -class's method tables which the category is loaded at runtime, -replacing those methods in case of a collision.</p> - -<p>In the standard environment, objects are allocated on the heap, and -their lifetime is manually managed using a reference count. This is -done using two instance methods which all classes are expected to -implement: <tt>retain</tt> increases the object's reference count by -1, whereas <tt>release</tt> decreases it by 1 and calls the instance -method <tt>dealloc</tt> if the count reaches 0. To simplify certain -operations, there is also an <span class="term">autorelease -pool</span>, a thread-local list of objects to call <tt>release</tt> -on later; an object can be added to this pool by -calling <tt>autorelease</tt> on it.</p> - -<p>Block pointers may be converted to type <tt>id</tt>; block objects -are laid out in a way that makes them compatible with Objective-C -objects. There is a builtin class that all block objects are -considered to be objects of; this class implements <tt>retain</tt> by -adjusting the reference count, not by calling <tt>Block_copy</tt>.</p> - -</div> <!-- meta.background --> - -<div id="meta.evolution"> -<h1>Evolution</h1> - -<p>ARC is under continual evolution, and this document must be updated -as the language progresses.</p> - -<p>If a change increases the expressiveness of the language, for -example by lifting a restriction or by adding new syntax, the change -will be annotated with a revision marker, like so:</p> - -<blockquote> - ARC applies to Objective-C pointer types, block pointer types, and - <span class="revision"><span class="whenRevised">[beginning Apple - 8.0, LLVM 3.8]</span> BPTRs declared within <code>extern - "BCPL"</code> blocks</span>. -</blockquote> - -<p>For now, it is sensible to version this document by the releases of -its sole implementation (and its host project), clang. -<q>LLVM X.Y</q> refers to an open-source release of clang from the -LLVM project. <q>Apple X.Y</q> refers to an Apple-provided release of -the Apple LLVM Compiler. Other organizations that prepare their own, -separately-versioned clang releases and wish to maintain similar -information in this document should send requests to cfe-dev.</p> - -<p>If a change decreases the expressiveness of the language, for -example by imposing a new restriction, this should be taken as an -oversight in the original specification and something to be avoided -in all versions. Such changes are generally to be avoided.</p> - -</div> <!-- meta.evolution --> - -</div> <!-- meta --> - -<div id="general"> -<h1>General</h1> - -<p>Automatic Reference Counting implements automatic memory management -for Objective-C objects and blocks, freeing the programmer from the -need to explicitly insert retains and releases. It does not provide a -cycle collector; users must explicitly manage the lifetime of their -objects, breaking cycles manually or with weak or unsafe -references.</p> - -<p>ARC may be explicitly enabled with the compiler -flag <tt>-fobjc-arc</tt>. It may also be explicitly disabled with the -compiler flag <tt>-fno-objc-arc</tt>. The last of these two flags -appearing on the compile line <q>wins</q>.</p> - -<p>If ARC is enabled, <tt>__has_feature(objc_arc)</tt> will expand to -1 in the preprocessor. For more information about <tt>__has_feature</tt>, -see the <a href="LanguageExtensions.html#__has_feature_extension">language -extensions</a> document.</p> - -</div> <!-- general --> - -<div id="objects"> -<h1>Retainable object pointers</h1> - -<p>This section describes retainable object pointers, their basic -operations, and the restrictions imposed on their use under ARC. Note -in particular that it covers the rules for pointer <em>values</em> -(patterns of bits indicating the location of a pointed-to object), not -pointer -<em>objects</em> (locations in memory which store pointer values). -The rules for objects are covered in the next section.</p> - -<p>A <span class="term">retainable object pointer</span> -(or <q>retainable pointer</q>) is a value of -a <span class="term">retainable object pointer type</span> -(<q>retainable type</q>). There are three kinds of retainable object -pointer types:</p> -<ul> -<li>block pointers (formed by applying the caret (<tt>^</tt>) -declarator sigil to a function type)</li> -<li>Objective-C object pointers (<tt>id</tt>, <tt>Class</tt>, <tt>NSFoo*</tt>, etc.)</li> -<li>typedefs marked with <tt>__attribute__((NSObject))</tt></li> -</ul> - -<p>Other pointer types, such as <tt>int*</tt> and <tt>CFStringRef</tt>, -are not subject to ARC's semantics and restrictions.</p> - -<div class="rationale"> - -<p>Rationale: We are not at liberty to require -all code to be recompiled with ARC; therefore, ARC must interoperate -with Objective-C code which manages retains and releases manually. In -general, there are three requirements in order for a -compiler-supported reference-count system to provide reliable -interoperation:</p> - -<ul> -<li>The type system must reliably identify which objects are to be -managed. An <tt>int*</tt> might be a pointer to a <tt>malloc</tt>'ed -array, or it might be an interior pointer to such an array, or it might -point to some field or local variable. In contrast, values of the -retainable object pointer types are never interior.</li> -<li>The type system must reliably indicate how to -manage objects of a type. This usually means that the type must imply -a procedure for incrementing and decrementing retain counts. -Supporting single-ownership objects requires a lot more explicit -mediation in the language.</li> -<li>There must be reliable conventions for whether and -when <q>ownership</q> is passed between caller and callee, for both -arguments and return values. Objective-C methods follow such a -convention very reliably, at least for system libraries on Mac OS X, -and functions always pass objects at +0. The C-based APIs for Core -Foundation objects, on the other hand, have much more varied transfer -semantics.</li> -</ul> -</div> <!-- rationale --> - -<p>The use of <tt>__attribute__((NSObject))</tt> typedefs is not -recommended. If it's absolutely necessary to use this attribute, be -very explicit about using the typedef, and do not assume that it will -be preserved by language features like <tt>__typeof</tt> and C++ -template argument substitution.</p> - -<div class="rationale"><p>Rationale: any compiler operation which -incidentally strips type <q>sugar</q> from a type will yield a type -without the attribute, which may result in unexpected -behavior.</p></div> - -<div id="objects.retains"> -<h1>Retain count semantics</h1> - -<p>A retainable object pointer is either a <span class="term">null -pointer</span> or a pointer to a valid object. Furthermore, if it has -block pointer type and is not <tt>null</tt> then it must actually be a -pointer to a block object, and if it has <tt>Class</tt> type (possibly -protocol-qualified) then it must actually be a pointer to a class -object. Otherwise ARC does not enforce the Objective-C type system as -long as the implementing methods follow the signature of the static -type. It is undefined behavior if ARC is exposed to an invalid -pointer.</p> - -<p>For ARC's purposes, a valid object is one with <q>well-behaved</q> -retaining operations. Specifically, the object must be laid out such -that the Objective-C message send machinery can successfully send it -the following messages:</p> - -<ul> -<li><tt>retain</tt>, taking no arguments and returning a pointer to -the object.</li> -<li><tt>release</tt>, taking no arguments and returning <tt>void</tt>.</li> -<li><tt>autorelease</tt>, taking no arguments and returning a pointer -to the object.</li> -</ul> - -<p>The behavior of these methods is constrained in the following ways. -The term <span class="term">high-level semantics</span> is an -intentionally vague term; the intent is that programmers must -implement these methods in a way such that the compiler, modifying -code in ways it deems safe according to these constraints, will not -violate their requirements. For example, if the user puts logging -statements in <tt>retain</tt>, they should not be surprised if those -statements are executed more or less often depending on optimization -settings. These constraints are not exhaustive of the optimization -opportunities: values held in local variables are subject to -additional restrictions, described later in this document.</p> - -<p>It is undefined behavior if a computation history featuring a send -of <tt>retain</tt> followed by a send of <tt>release</tt> to the same -object, with no intervening <tt>release</tt> on that object, is not -equivalent under the high-level semantics to a computation -history in which these sends are removed. Note that this implies that -these methods may not raise exceptions.</p> - -<p>It is undefined behavior if a computation history features any use -whatsoever of an object following the completion of a send -of <tt>release</tt> that is not preceded by a send of <tt>retain</tt> -to the same object.</p> - -<p>The behavior of <tt>autorelease</tt> must be equivalent to sending -<tt>release</tt> when one of the autorelease pools currently in scope -is popped. It may not throw an exception.</p> - -<p>When the semantics call for performing one of these operations on a -retainable object pointer, if that pointer is <tt>null</tt> then the -effect is a no-op.</p> - -<p>All of the semantics described in this document are subject to -additional <a href="#optimization">optimization rules</a> which permit -the removal or optimization of operations based on local knowledge of -data flow. The semantics describe the high-level behaviors that the -compiler implements, not an exact sequence of operations that a -program will be compiled into.</p> - -</div> <!-- objects.retains --> - -<div id="objects.operands"> -<h1>Retainable object pointers as operands and arguments</h1> - -<p>In general, ARC does not perform retain or release operations when -simply using a retainable object pointer as an operand within an -expression. This includes:</p> -<ul> -<li>loading a retainable pointer from an object with non-weak -<a href="#ownership">ownership</a>,</li> -<li>passing a retainable pointer as an argument to a function or -method, and</li> -<li>receiving a retainable pointer as the result of a function or -method call.</li> -</ul> - -<div class="rationale"><p>Rationale: while this might seem -uncontroversial, it is actually unsafe when multiple expressions are -evaluated in <q>parallel</q>, as with binary operators and calls, -because (for example) one expression might load from an object while -another writes to it. However, C and C++ already call this undefined -behavior because the evaluations are unsequenced, and ARC simply -exploits that here to avoid needing to retain arguments across a large -number of calls.</p></div> - -<p>The remainder of this section describes exceptions to these rules, -how those exceptions are detected, and what those exceptions imply -semantically.</p> - -<div id="objects.operands.consumed"> -<h1>Consumed parameters</h1> - -<p>A function or method parameter of retainable object pointer type -may be marked as <span class="term">consumed</span>, signifying that -the callee expects to take ownership of a +1 retain count. This is -done by adding the <tt>ns_consumed</tt> attribute to the parameter -declaration, like so:</p> - -<pre>void foo(__attribute((ns_consumed)) id x); -- (void) foo: (id) __attribute((ns_consumed)) x;</pre> - -<p>This attribute is part of the type of the function or method, not -the type of the parameter. It controls only how the argument is -passed and received.</p> - -<p>When passing such an argument, ARC retains the argument prior to -making the call.</p> - -<p>When receiving such an argument, ARC releases the argument at the -end of the function, subject to the usual optimizations for local -values.</p> - -<div class="rationale"><p>Rationale: this formalizes direct transfers -of ownership from a caller to a callee. The most common scenario here -is passing the <tt>self</tt> parameter to <tt>init</tt>, but it is -useful to generalize. Typically, local optimization will remove any -extra retains and releases: on the caller side the retain will be -merged with a +1 source, and on the callee side the release will be -rolled into the initialization of the parameter.</p></div> - -<p>The implicit <tt>self</tt> parameter of a method may be marked as -consumed by adding <tt>__attribute__((ns_consumes_self))</tt> to the -method declaration. Methods in the <tt>init</tt> -<a href="#family">family</a> are treated as if they were implicitly -marked with this attribute.</p> - -<p>It is undefined behavior if an Objective-C message send to a method -with <tt>ns_consumed</tt> parameters (other than self) is made with a -null receiver. It is undefined behavior if the method to which an -Objective-C message send statically resolves to has a different set -of <tt>ns_consumed</tt> parameters than the method it dynamically -resolves to. It is undefined behavior if a block or function call is -made through a static type with a different set of <tt>ns_consumed</tt> -parameters than the implementation of the called block or function.</p> - -<div class="rationale"><p>Rationale: consumed parameters with null -receiver are a guaranteed leak. Mismatches with consumed parameters -will cause over-retains or over-releases, depending on the direction. -The rule about function calls is really just an application of the -existing C/C++ rule about calling functions through an incompatible -function type, but it's useful to state it explicitly.</p></div> - -</div> <!-- objects.operands.consumed --> - -<div id="objects.operands.retained-returns"> -<h1>Retained return values</h1> - -<p>A function or method which returns a retainable object pointer type -may be marked as returning a retained value, signifying that the -caller expects to take ownership of a +1 retain count. This is done -by adding the <tt>ns_returns_retained</tt> attribute to the function or -method declaration, like so:</p> - -<pre>id foo(void) __attribute((ns_returns_retained)); -- (id) foo __attribute((ns_returns_retained));</pre> - -<p>This attribute is part of the type of the function or method.</p> - -<p>When returning from such a function or method, ARC retains the -value at the point of evaluation of the return statement, before -leaving all local scopes.</p> - -<p>When receiving a return result from such a function or method, ARC -releases the value at the end of the full-expression it is contained -within, subject to the usual optimizations for local values.</p> - -<div class="rationale"><p>Rationale: this formalizes direct transfers of -ownership from a callee to a caller. The most common scenario this -models is the retained return from <tt>init</tt>, <tt>alloc</tt>, -<tt>new</tt>, and <tt>copy</tt> methods, but there are other cases in -the frameworks. After optimization there are typically no extra -retains and releases required.</p></div> - -<p>Methods in -the <tt>alloc</tt>, <tt>copy</tt>, <tt>init</tt>, <tt>mutableCopy</tt>, -and <tt>new</tt> <a href="#family">families</a> are implicitly marked -<tt>__attribute__((ns_returns_retained))</tt>. This may be suppressed -by explicitly marking the -method <tt>__attribute__((ns_returns_not_retained))</tt>.</p> - -<p>It is undefined behavior if the method to which an Objective-C -message send statically resolves has different retain semantics on its -result from the method it dynamically resolves to. It is undefined -behavior if a block or function call is made through a static type -with different retain semantics on its result from the implementation -of the called block or function.</p> - -<div class="rationale"><p>Rationale: Mismatches with returned results -will cause over-retains or over-releases, depending on the direction. -Again, the rule about function calls is really just an application of -the existing C/C++ rule about calling functions through an -incompatible function type.</p></div> - -</div> <!-- objects.operands.retained-returns --> - -<div id="objects.operands.other-returns"> -<h1>Unretained return values</h1> - -<p>A method or function which returns a retainable object type but -does not return a retained value must ensure that the object is -still valid across the return boundary.</p> - -<p>When returning from such a function or method, ARC retains the -value at the point of evaluation of the return statement, then leaves -all local scopes, and then balances out the retain while ensuring that -the value lives across the call boundary. In the worst case, this may -involve an <tt>autorelease</tt>, but callers must not assume that the -value is actually in the autorelease pool.</p> - -<p>ARC performs no extra mandatory work on the caller side, although -it may elect to do something to shorten the lifetime of the returned -value.</p> - -<div class="rationale"><p>Rationale: it is common in non-ARC code to not -return an autoreleased value; therefore the convention does not force -either path. It is convenient to not be required to do unnecessary -retains and autoreleases; this permits optimizations such as eliding -retain/autoreleases when it can be shown that the original pointer -will still be valid at the point of return.</p></div> - -<p>A method or function may be marked -with <tt>__attribute__((ns_returns_autoreleased))</tt> to indicate -that it returns a pointer which is guaranteed to be valid at least as -long as the innermost autorelease pool. There are no additional -semantics enforced in the definition of such a method; it merely -enables optimizations in callers.</p> - -</div> <!-- objects.operands.other-returns --> - -<div id="objects.operands.casts"> -<h1>Bridged casts</h1> - -<p>A <span class="term">bridged cast</span> is a C-style cast -annotated with one of three keywords:</p> - -<ul> -<li><tt>(__bridge T) op</tt> casts the operand to the destination -type <tt>T</tt>. If <tt>T</tt> is a retainable object pointer type, -then <tt>op</tt> must have a non-retainable pointer type. -If <tt>T</tt> is a non-retainable pointer type, then <tt>op</tt> must -have a retainable object pointer type. Otherwise the cast is -ill-formed. There is no transfer of ownership, and ARC inserts -no retain operations.</li> - -<li><tt>(__bridge_retained T) op</tt> casts the operand, which must -have retainable object pointer type, to the destination type, which -must be a non-retainable pointer type. ARC retains the value, subject -to the usual optimizations on local values, and the recipient is -responsible for balancing that +1.</li> - -<li><tt>(__bridge_transfer T) op</tt> casts the operand, which must -have non-retainable pointer type, to the destination type, which must -be a retainable object pointer type. ARC will release the value at -the end of the enclosing full-expression, subject to the usual -optimizations on local values.</li> -</ul> - -<p>These casts are required in order to transfer objects in and out of -ARC control; see the rationale in the section -on <a href="#objects.restrictions.conversion">conversion of retainable -object pointers</a>.</p> - -<p>Using a <tt>__bridge_retained</tt> or <tt>__bridge_transfer</tt> -cast purely to convince ARC to emit an unbalanced retain or release, -respectively, is poor form.</p> - -</div> <!-- objects.operands.casts --> - -</div> <!-- objects.operands --> - -<div id="objects.restrictions"> -<h1>Restrictions</h1> - -<div id="objects.restrictions.conversion"> -<h1>Conversion of retainable object pointers</h1> - -<p>In general, a program which attempts to implicitly or explicitly -convert a value of retainable object pointer type to any -non-retainable type, or vice-versa, is ill-formed. For example, an -Objective-C object pointer shall not be converted to <tt>void*</tt>. -As an exception, cast to <tt>intptr_t</tt> is allowed because such -casts are not transferring ownership. The <a href="#objects.operands.casts">bridged -casts</a> may be used to perform these conversions where -necessary.</p> - -<div class="rationale"><p>Rationale: we cannot ensure the correct -management of the lifetime of objects if they may be freely passed -around as unmanaged types. The bridged casts are provided so that the -programmer may explicitly describe whether the cast transfers control -into or out of ARC.</p></div> - -<p>However, the following exceptions apply.</p> - -</div> <!-- objects.restrictions.conversion --> - -<div id="objects.restrictions.conversion-exception-known"> -<h1>Conversion to retainable object pointer type of - expressions with known semantics</h1> - -<p><span class="revision"><span class="whenRevised">[beginning Apple - 4.0, LLVM 3.1]</span> These exceptions have been greatly expanded; - they previously applied only to a much-reduced subset which is - difficult to categorize but which included null pointers, message - sends (under the given rules), and the various global constants.</span></p> - -<p>An unbridged conversion to a retainable object pointer type from a -type other than a retainable object pointer type is ill-formed, as -discussed above, unless the operand of the cast has a syntactic form -which is known retained, known unretained, or known -retain-agnostic.</p> - -<p>An expression is <span class="term">known retain-agnostic</span> if -it is:</p> -<ul> -<li>an Objective-C string literal,</li> -<li>a load from a <tt>const</tt> system global variable of -<a href="#misc.c-retainable">C retainable pointer type</a>, or</li> -<li>a null pointer constant.</li> -</ul> - -<p>An expression is <span class="term">known unretained</span> if it -is an rvalue of <a href="#misc.c-retainable">C retainable -pointer type</a> and it is:</p> -<ul> -<li>a direct call to a function, and either that function has the - <tt>cf_returns_not_retained</tt> attribute or it is an - <a href="#misc.c-retainable.audit">audited</a> function that does not - have the <tt>cf_returns_retained</tt> attribute and does not follow - the create/copy naming convention,</li> -<li>a message send, and the declared method either has - the <tt>cf_returns_not_retained</tt> attribute or it has neither - the <tt>cf_returns_retained</tt> attribute nor a - <a href="#family">selector family</a> that implies a retained - result.</li> -</ul> - -<p>An expression is <span class="term">known retained</span> if it is -an rvalue of <a href="#misc.c-retainable">C retainable pointer type</a> -and it is:</p> -<ul> -<li>a message send, and the declared method either has the - <tt>cf_returns_retained</tt> attribute, or it does not have - the <tt>cf_returns_not_retained</tt> attribute but it does have a - <a href="#family">selector family</a> that implies a retained - result.</li> -</ul> - -<p>Furthermore:</p> -<ul> -<li>a comma expression is classified according to its right-hand side,</li> -<li>a statement expression is classified according to its result -expression, if it has one,</li> -<li>an lvalue-to-rvalue conversion applied to an Objective-C property -lvalue is classified according to the underlying message send, and</li> -<li>a conditional operator is classified according to its second and -third operands, if they agree in classification, or else the other -if one is known retain-agnostic.</li> -</ul> - -<p>If the cast operand is known retained, the conversion is treated as -a <tt>__bridge_transfer</tt> cast. If the cast operand is known -unretained or known retain-agnostic, the conversion is treated as -a <tt>__bridge</tt> cast.</p> - -<div class="rationale"><p>Rationale: Bridging casts are annoying. -Absent the ability to completely automate the management of CF -objects, however, we are left with relatively poor attempts to reduce -the need for a glut of explicit bridges. Hence these rules.</p> - -<p>We've so far consciously refrained from implicitly turning retained -CF results from function calls into <tt>__bridge_transfer</tt> casts. -The worry is that some code patterns — for example, creating a -CF value, assigning it to an ObjC-typed local, and then -calling <tt>CFRelease</tt> when done — are a bit too likely to -be accidentally accepted, leading to mysterious behavior.</p></div> - -</div> <!-- objects.restrictions.conversion-exception-known --> - -<div id="objects.restrictions.conversion-exception-contextual"> -<h1>Conversion from retainable object pointer type in certain contexts</h1> - -<p><span class="revision"><span class="whenRevised">[beginning Apple - 4.0, LLVM 3.1]</span></span></p> - -<p>If an expression of retainable object pointer type is explicitly -cast to a <a href="#misc.c-retainable">C retainable pointer type</a>, -the program is ill-formed as discussed above unless the result is -immediately used:</p> - -<ul> -<li>to initialize a parameter in an Objective-C message send where the -parameter is not marked with the <tt>cf_consumed</tt> attribute, or</li> -<li>to initialize a parameter in a direct call to -an <a href="#misc.c-retainable.audit">audited</a> function where the -parameter is not marked with the <tt>cf_consumed</tt> attribute.</li> -</ul> - -<div class="rationale"><p>Rationale: Consumed parameters are left out -because ARC would naturally balance them with a retain, which was -judged too treacherous. This is in part because several of the most -common consuming functions are in the <tt>Release</tt> family, and it -would be quite unfortunate for explicit releases to be silently -balanced out in this way.</p></div> - -</div> <!-- objects.restrictions.conversion-exception-contextual --> - -</div> <!-- objects.restrictions --> - -</div> <!-- objects --> - -<div id="ownership"> -<h1>Ownership qualification</h1> - -<p>This section describes the behavior of <em>objects</em> of -retainable object pointer type; that is, locations in memory which -store retainable object pointers.</p> - -<p>A type is a <span class="term">retainable object owner type</span> -if it is a retainable object pointer type or an array type whose -element type is a retainable object owner type.</p> - -<p>An <span class="term">ownership qualifier</span> is a type -qualifier which applies only to retainable object owner types. An array type is -ownership-qualified according to its element type, and adding an ownership -qualifier to an array type so qualifies its element type.</p> - -<p>A program is ill-formed if it attempts to apply an ownership qualifier -to a type which is already ownership-qualified, even if it is the same -qualifier. There is a single exception to this rule: an ownership qualifier -may be applied to a substituted template type parameter, which overrides the -ownership qualifier provided by the template argument.</p> - -<p>Except as described under -the <a href="#ownership.inference">inference rules</a>, a program is -ill-formed if it attempts to form a pointer or reference type to a -retainable object owner type which lacks an ownership qualifier.</p> - -<div class="rationale"><p>Rationale: these rules, together with the -inference rules, ensure that all objects and lvalues of retainable -object pointer type have an ownership qualifier. The ability to override an ownership qualifier during template substitution is required to counteract the <a href="#ownership.inference.template_arguments">inference of <tt>__strong</tt> for template type arguments</a>. </p></div> - -<p>There are four ownership qualifiers:</p> - -<ul> -<li><tt>__autoreleasing</tt></li> -<li><tt>__strong</tt></li> -<li><tt>__unsafe_unretained</tt></li> -<li><tt>__weak</tt></li> -</ul> - -<p>A type is <span class="term">nontrivially ownership-qualified</span> -if it is qualified with <tt>__autoreleasing</tt>, <tt>__strong</tt>, or -<tt>__weak</tt>.</p> - -<div id="ownership.spelling"> -<h1>Spelling</h1> - -<p>The names of the ownership qualifiers are reserved for the -implementation. A program may not assume that they are or are not -implemented with macros, or what those macros expand to.</p> - -<p>An ownership qualifier may be written anywhere that any other type -qualifier may be written.</p> - -<p>If an ownership qualifier appears in -the <i>declaration-specifiers</i>, the following rules apply:</p> - -<ul> -<li>if the type specifier is a retainable object owner type, the -qualifier applies to that type;</li> -<li>if the outermost non-array part of the declarator is a pointer or -block pointer, the qualifier applies to that type;</li> -<li>otherwise the program is ill-formed.</li> -</ul> - -<p>If an ownership qualifier appears on the declarator name, or on the -declared object, it is applied to outermost pointer or block-pointer -type.</p> - -<p>If an ownership qualifier appears anywhere else in a declarator, it -applies to the type there.</p> - -<div id="ownership.spelling.property"> -<h1>Property declarations</h1> - -<p>A property of retainable object pointer type may have ownership. -If the property's type is ownership-qualified, then the property has -that ownership. If the property has one of the following modifiers, -then the property has the corresponding ownership. A property is -ill-formed if it has conflicting sources of ownership, or if it has -redundant ownership modifiers, or if it has <tt>__autoreleasing</tt> -ownership.</p> - -<ul> -<li><tt>assign</tt> implies <tt>__unsafe_unretained</tt> ownership.</li> -<li><tt>copy</tt> implies <tt>__strong</tt> ownership, as well as the - usual behavior of copy semantics on the setter.</li> -<li><tt>retain</tt> implies <tt>__strong</tt> ownership.</li> -<li><tt>strong</tt> implies <tt>__strong</tt> ownership.</li> -<li><tt>unsafe_unretained</tt> implies <tt>__unsafe_unretained</tt> - ownership.</li> -<li><tt>weak</tt> implies <tt>__weak</tt> ownership.</li> -</ul> - -<p>With the exception of <tt>weak</tt>, these modifiers are available -in non-ARC modes.</p> - -<p>A property's specified ownership is preserved in its metadata, but -otherwise the meaning is purely conventional unless the property is -synthesized. If a property is synthesized, then the -<span class="term">associated instance variable</span> is the -instance variable which is named, possibly implicitly, by the -<tt>@synthesize</tt> declaration. If the associated instance variable -already exists, then its ownership qualification must equal the -ownership of the property; otherwise, the instance variable is created -with that ownership qualification.</p> - -<p>A property of retainable object pointer type which is synthesized -without a source of ownership has the ownership of its associated -instance variable, if it already exists; otherwise, -<span class="revision"><span class="whenRevised">[beginning Apple 3.1, -LLVM 3.1]</span> its ownership is implicitly <tt>strong</tt></span>. -Prior to this revision, it was ill-formed to synthesize such a -property.</p> - -<div class="rationale"><p>Rationale: using <tt>strong</tt> by default -is safe and consistent with the generic ARC rule about -<a href="#ownership.inference.variables">inferring ownership</a>. It -is, unfortunately, inconsistent with the non-ARC rule which states -that such properties are implicitly <tt>assign</tt>. However, that -rule is clearly untenable in ARC, since it leads to default-unsafe -code. The main merit to banning the properties is to avoid confusion -with non-ARC practice, which did not ultimately strike us as -sufficient to justify requiring extra syntax and (more importantly) -forcing novices to understand ownership rules just to declare a -property when the default is so reasonable. Changing the rule away -from non-ARC practice was acceptable because we had conservatively -banned the synthesis in order to give ourselves exactly this -leeway.</p></div> - -<p>Applying <tt>__attribute__((NSObject))</tt> to a property not of -retainable object pointer type has the same behavior it does outside -of ARC: it requires the property type to be some sort of pointer and -permits the use of modifiers other than <tt>assign</tt>. These -modifiers only affect the synthesized getter and setter; direct -accesses to the ivar (even if synthesized) still have primitive -semantics, and the value in the ivar will not be automatically -released during deallocation.</p> - -</div> <!-- ownership.spelling.property --> - -</div> <!-- ownership.spelling --> - -<div id="ownership.semantics"> -<h1>Semantics</h1> - -<p>There are five <span class="term">managed operations</span> which -may be performed on an object of retainable object pointer type. Each -qualifier specifies different semantics for each of these operations. -It is still undefined behavior to access an object outside of its -lifetime.</p> - -<p>A load or store with <q>primitive semantics</q> has the same -semantics as the respective operation would have on an <tt>void*</tt> -lvalue with the same alignment and non-ownership qualification.</p> - -<p><span class="term">Reading</span> occurs when performing a -lvalue-to-rvalue conversion on an object lvalue.</p> - -<ul> -<li>For <tt>__weak</tt> objects, the current pointee is retained and -then released at the end of the current full-expression. This must -execute atomically with respect to assignments and to the final -release of the pointee.</li> -<li>For all other objects, the lvalue is loaded with primitive -semantics.</li> -</ul> - -<p><span class="term">Assignment</span> occurs when evaluating -an assignment operator. The semantics vary based on the qualification:</p> -<ul> -<li>For <tt>__strong</tt> objects, the new pointee is first retained; -second, the lvalue is loaded with primitive semantics; third, the new -pointee is stored into the lvalue with primitive semantics; and -finally, the old pointee is released. This is not performed -atomically; external synchronization must be used to make this safe in -the face of concurrent loads and stores.</li> -<li>For <tt>__weak</tt> objects, the lvalue is updated to point to the -new pointee, unless the new pointee is an object currently undergoing -deallocation, in which case the lvalue is updated to a null pointer. -This must execute atomically with respect to other assignments to the -object, to reads from the object, and to the final release of the new -pointee.</li> -<li>For <tt>__unsafe_unretained</tt> objects, the new pointee is -stored into the lvalue using primitive semantics.</li> -<li>For <tt>__autoreleasing</tt> objects, the new pointee is retained, -autoreleased, and stored into the lvalue using primitive semantics.</li> -</ul> - -<p><span class="term">Initialization</span> occurs when an object's -lifetime begins, which depends on its storage duration. -Initialization proceeds in two stages:</p> -<ol> -<li>First, a null pointer is stored into the lvalue using primitive -semantics. This step is skipped if the object -is <tt>__unsafe_unretained</tt>.</li> -<li>Second, if the object has an initializer, that expression is -evaluated and then assigned into the object using the usual assignment -semantics.</li> -</ol> - -<p><span class="term">Destruction</span> occurs when an object's -lifetime ends. In all cases it is semantically equivalent to -assigning a null pointer to the object, with the proviso that of -course the object cannot be legally read after the object's lifetime -ends.</p> - -<p><span class="term">Moving</span> occurs in specific situations -where an lvalue is <q>moved from</q>, meaning that its current pointee -will be used but the object may be left in a different (but still -valid) state. This arises with <tt>__block</tt> variables and rvalue -references in C++. For <tt>__strong</tt> lvalues, moving is equivalent -to loading the lvalue with primitive semantics, writing a null pointer -to it with primitive semantics, and then releasing the result of the -load at the end of the current full-expression. For all other -lvalues, moving is equivalent to reading the object.</p> - -</div> <!-- ownership.semantics --> - -<div id="ownership.restrictions"> -<h1>Restrictions</h1> - -<div id="ownership.restrictions.weak"> -<h1>Weak-unavailable types</h1> - -<p>It is explicitly permitted for Objective-C classes to not -support <tt>__weak</tt> references. It is undefined behavior to -perform an operation with weak assignment semantics with a pointer to -an Objective-C object whose class does not support <tt>__weak</tt> -references.</p> - -<div class="rationale"><p>Rationale: historically, it has been -possible for a class to provide its own reference-count implementation -by overriding <tt>retain</tt>, <tt>release</tt>, etc. However, weak -references to an object require coordination with its class's -reference-count implementation because, among other things, weak loads -and stores must be atomic with respect to the final release. -Therefore, existing custom reference-count implementations will -generally not support weak references without additional effort. This -is unavoidable without breaking binary compatibility.</p></div> - -<p>A class may indicate that it does not support weak references by -providing the <tt>objc_arc_weak_unavailable</tt> attribute on the -class's interface declaration. A retainable object pointer type -is <span class="term">weak-unavailable</span> if is a pointer to an -(optionally protocol-qualified) Objective-C class <tt>T</tt> -where <tt>T</tt> or one of its superclasses has -the <tt>objc_arc_weak_unavailable</tt> attribute. A program is -ill-formed if it applies the <tt>__weak</tt> ownership qualifier to a -weak-unavailable type or if the value operand of a weak assignment -operation has a weak-unavailable type.</p> -</div> <!-- ownership.restrictions.weak --> - -<div id="ownership.restrictions.autoreleasing"> -<h1>Storage duration of <tt>__autoreleasing</tt> objects</h1> - -<p>A program is ill-formed if it declares an <tt>__autoreleasing</tt> -object of non-automatic storage duration. A program is ill-formed -if it captures an <tt>__autoreleasing</tt> object in a block or, -unless by reference, in a C++11 lambda.</p> - -<div class="rationale"><p>Rationale: autorelease pools are tied to the -current thread and scope by their nature. While it is possible to -have temporary objects whose instance variables are filled with -autoreleased objects, there is no way that ARC can provide any sort of -safety guarantee there.</p></div> - -<p>It is undefined behavior if a non-null pointer is assigned to -an <tt>__autoreleasing</tt> object while an autorelease pool is in -scope and then that object is read after the autorelease pool's scope -is left.</p> - -</div> - -<div id="ownership.restrictions.conversion.indirect"> -<h1>Conversion of pointers to ownership-qualified types</h1> - -<p>A program is ill-formed if an expression of type <tt>T*</tt> is -converted, explicitly or implicitly, to the type <tt>U*</tt>, -where <tt>T</tt> and <tt>U</tt> have different ownership -qualification, unless:</p> -<ul> -<li><tt>T</tt> is qualified with <tt>__strong</tt>, - <tt>__autoreleasing</tt>, or <tt>__unsafe_unretained</tt>, and - <tt>U</tt> is qualified with both <tt>const</tt> and - <tt>__unsafe_unretained</tt>; or</li> -<li>either <tt>T</tt> or <tt>U</tt> is <tt>cv void</tt>, where -<tt>cv</tt> is an optional sequence of non-ownership qualifiers; or</li> -<li>the conversion is requested with a <tt>reinterpret_cast</tt> in - Objective-C++; or</li> -<li>the conversion is a -well-formed <a href="#ownership.restrictions.pass_by_writeback">pass-by-writeback</a>.</li> -</ul> - -<p>The analogous rule applies to <tt>T&</tt> and <tt>U&</tt> in -Objective-C++.</p> - -<div class="rationale"><p>Rationale: these rules provide a reasonable -level of type-safety for indirect pointers, as long as the underlying -memory is not deallocated. The conversion to <tt>const -__unsafe_unretained</tt> is permitted because the semantics of reads -are equivalent across all these ownership semantics, and that's a very -useful and common pattern. The interconversion with <tt>void*</tt> is -useful for allocating memory or otherwise escaping the type system, -but use it carefully. <tt>reinterpret_cast</tt> is considered to be -an obvious enough sign of taking responsibility for any -problems.</p></div> - -<p>It is undefined behavior to access an ownership-qualified object -through an lvalue of a differently-qualified type, except that any -non-<tt>__weak</tt> object may be read through -an <tt>__unsafe_unretained</tt> lvalue.</p> - -<p>It is undefined behavior if a managed operation is performed on -a <tt>__strong</tt> or <tt>__weak</tt> object without a guarantee that -it contains a primitive zero bit-pattern, or if the storage for such -an object is freed or reused without the object being first assigned a -null pointer.</p> - -<div class="rationale"><p>Rationale: ARC cannot differentiate between -an assignment operator which is intended to <q>initialize</q> dynamic -memory and one which is intended to potentially replace a value. -Therefore the object's pointer must be valid before letting ARC at it. -Similarly, C and Objective-C do not provide any language hooks for -destroying objects held in dynamic memory, so it is the programmer's -responsibility to avoid leaks (<tt>__strong</tt> objects) and -consistency errors (<tt>__weak</tt> objects).</p> - -<p>These requirements are followed automatically in Objective-C++ when -creating objects of retainable object owner type with <tt>new</tt> -or <tt>new[]</tt> and destroying them with <tt>delete</tt>, -<tt>delete[]</tt>, or a pseudo-destructor expression. Note that -arrays of nontrivially-ownership-qualified type are not ABI compatible -with non-ARC code because the element type is non-POD: such arrays -that are <tt>new[]</tt>'d in ARC translation units cannot -be <tt>delete[]</tt>'d in non-ARC translation units and -vice-versa.</p></div> - -</div> - -<div id="ownership.restrictions.pass_by_writeback"> -<h1>Passing to an out parameter by writeback</h1> - -<p>If the argument passed to a parameter of type -<tt>T __autoreleasing *</tt> has type <tt>U oq *</tt>, -where <tt>oq</tt> is an ownership qualifier, then the argument is a -candidate for <span class="term">pass-by-writeback</span> if:</p> - -<ul> -<li><tt>oq</tt> is <tt>__strong</tt> or <tt>__weak</tt>, and</li> -<li>it would be legal to initialize a <tt>T __strong *</tt> with -a <tt>U __strong *</tt>.</li> -</ul> - -<p>For purposes of overload resolution, an implicit conversion -sequence requiring a pass-by-writeback is always worse than an -implicit conversion sequence not requiring a pass-by-writeback.</p> - -<p>The pass-by-writeback is ill-formed if the argument expression does -not have a legal form:</p> - -<ul> -<li><tt>&var</tt>, where <tt>var</tt> is a scalar variable of -automatic storage duration with retainable object pointer type</li> -<li>a conditional expression where the second and third operands are -both legal forms</li> -<li>a cast whose operand is a legal form</li> -<li>a null pointer constant</li> -</ul> - -<div class="rationale"><p>Rationale: the restriction in the form of -the argument serves two purposes. First, it makes it impossible to -pass the address of an array to the argument, which serves to protect -against an otherwise serious risk of mis-inferring an <q>array</q> -argument as an out-parameter. Second, it makes it much less likely -that the user will see confusing aliasing problems due to the -implementation, below, where their store to the writeback temporary is -not immediately seen in the original argument variable.</p></div> - -<p>A pass-by-writeback is evaluated as follows:</p> -<ol> -<li>The argument is evaluated to yield a pointer <tt>p</tt> of - type <tt>U oq *</tt>.</li> -<li>If <tt>p</tt> is a null pointer, then a null pointer is passed as - the argument, and no further work is required for the pass-by-writeback.</li> -<li>Otherwise, a temporary of type <tt>T __autoreleasing</tt> is - created and initialized to a null pointer.</li> -<li>If the parameter is not an Objective-C method parameter marked - <tt>out</tt>, then <tt>*p</tt> is read, and the result is written - into the temporary with primitive semantics.</li> -<li>The address of the temporary is passed as the argument to the - actual call.</li> -<li>After the call completes, the temporary is loaded with primitive - semantics, and that value is assigned into <tt>*p</tt>.</li> -</ol> - -<div class="rationale"><p>Rationale: this is all admittedly -convoluted. In an ideal world, we would see that a local variable is -being passed to an out-parameter and retroactively modify its type to -be <tt>__autoreleasing</tt> rather than <tt>__strong</tt>. This would -be remarkably difficult and not always well-founded under the C type -system. However, it was judged unacceptably invasive to require -programmers to write <tt>__autoreleasing</tt> on all the variables -they intend to use for out-parameters. This was the least bad -solution.</p></div> - -</div> - -<div id="ownership.restrictions.records"> -<h1>Ownership-qualified fields of structs and unions</h1> - -<p>A program is ill-formed if it declares a member of a C struct or -union to have a nontrivially ownership-qualified type.</p> - -<div class="rationale"><p>Rationale: the resulting type would be -non-POD in the C++ sense, but C does not give us very good language -tools for managing the lifetime of aggregates, so it is more -convenient to simply forbid them. It is still possible to manage this -with a <tt>void*</tt> or an <tt>__unsafe_unretained</tt> -object.</p></div> - -<p>This restriction does not apply in Objective-C++. However, -nontrivally ownership-qualified types are considered non-POD: in C++11 -terms, they are not trivially default constructible, copy -constructible, move constructible, copy assignable, move assignable, -or destructible. It is a violation of C++'s One Definition Rule to use -a class outside of ARC that, under ARC, would have a nontrivially -ownership-qualified member.</p> - -<div class="rationale"><p>Rationale: unlike in C, we can express all -the necessary ARC semantics for ownership-qualified subobjects as -suboperations of the (default) special member functions for the class. -These functions then become non-trivial. This has the non-obvious -result that the class will have a non-trivial copy constructor and -non-trivial destructor; if this would not normally be true outside of -ARC, objects of the type will be passed and returned in an -ABI-incompatible manner.</p></div> - -</div> - -</div> - -<div id="ownership.inference"> -<h1>Ownership inference</h1> - -<div id="ownership.inference.variables"> -<h1>Objects</h1> - -<p>If an object is declared with retainable object owner type, but -without an explicit ownership qualifier, its type is implicitly -adjusted to have <tt>__strong</tt> qualification.</p> - -<p>As a special case, if the object's base type is <tt>Class</tt> -(possibly protocol-qualified), the type is adjusted to -have <tt>__unsafe_unretained</tt> qualification instead.</p> - -</div> - -<div id="ownership.inference.indirect_parameters"> -<h1>Indirect parameters</h1> - -<p>If a function or method parameter has type <tt>T*</tt>, where -<tt>T</tt> is an ownership-unqualified retainable object pointer type, -then:</p> - -<ul> -<li>if <tt>T</tt> is <tt>const</tt>-qualified or <tt>Class</tt>, then -it is implicitly qualified with <tt>__unsafe_unretained</tt>;</li> -<li>otherwise, it is implicitly qualified -with <tt>__autoreleasing</tt>.</li> -</ul> - -<div class="rationale"><p>Rationale: <tt>__autoreleasing</tt> exists -mostly for this case, the Cocoa convention for out-parameters. Since -a pointer to <tt>const</tt> is obviously not an out-parameter, we -instead use a type more useful for passing arrays. If the user -instead intends to pass in a <em>mutable</em> array, inferring -<tt>__autoreleasing</tt> is the wrong thing to do; this directs some -of the caution in the following rules about writeback.</p></div> - -<p>Such a type written anywhere else would be ill-formed by the -general rule requiring ownership qualifiers.</p> - -<p>This rule does not apply in Objective-C++ if a parameter's type is -dependent in a template pattern and is only <em>instantiated</em> to -a type which would be a pointer to an unqualified retainable object -pointer type. Such code is still ill-formed.</p> - -<div class="rationale"><p>Rationale: the convention is very unlikely -to be intentional in template code.</p></div> - -</div> <!-- ownership.inference.indirect_parameters --> - -<div id="ownership.inference.template_arguments"> -<h1>Template arguments</h1> - -<p>If a template argument for a template type parameter is an -retainable object owner type that does not have an explicit ownership -qualifier, it is adjusted to have <tt>__strong</tt> -qualification. This adjustment occurs regardless of whether the -template argument was deduced or explicitly specified. </p> - -<div class="rationale"><p>Rationale: <tt>__strong</tt> is a useful default for containers (e.g., <tt>std::vector<id></tt>), which would otherwise require explicit qualification. Moreover, unqualified retainable object pointer types are unlikely to be useful within templates, since they generally need to have a qualifier applied to the before being used.</p></div> - -</div> <!-- ownership.inference.template_arguments --> -</div> <!-- ownership.inference --> -</div> <!-- ownership --> - - -<div id="family"> -<h1>Method families</h1> - -<p>An Objective-C method may fall into a <span class="term">method -family</span>, which is a conventional set of behaviors ascribed to it -by the Cocoa conventions.</p> - -<p>A method is in a certain method family if:</p> -<ul> -<li>it has a <tt>objc_method_family</tt> attribute placing it in that - family; or if not that,</li> -<li>it does not have an <tt>objc_method_family</tt> attribute placing - it in a different or no family, and</li> -<li>its selector falls into the corresponding selector family, and</li> -<li>its signature obeys the added restrictions of the method family.</li> -</ul> - -<p>A selector is in a certain selector family if, ignoring any leading -underscores, the first component of the selector either consists -entirely of the name of the method family or it begins with that name -followed by a character other than a lowercase letter. For -example, <tt>_perform:with:</tt> and <tt>performWith:</tt> would fall -into the <tt>perform</tt> family (if we recognized one), -but <tt>performing:with</tt> would not.</p> - -<p>The families and their added restrictions are:</p> - -<ul> -<li><tt>alloc</tt> methods must return a retainable object pointer type.</li> -<li><tt>copy</tt> methods must return a retainable object pointer type.</li> -<li><tt>mutableCopy</tt> methods must return a retainable object pointer type.</li> -<li><tt>new</tt> methods must return a retainable object pointer type.</li> -<li><tt>init</tt> methods must be instance methods and must return an -Objective-C pointer type. Additionally, a program is ill-formed if it -declares or contains a call to an <tt>init</tt> method whose return -type is neither <tt>id</tt> nor a pointer to a super-class or -sub-class of the declaring class (if the method was declared on -a class) or the static receiver type of the call (if it was declared -on a protocol). - -<div class="rationale"><p>Rationale: there are a fair number of existing -methods with <tt>init</tt>-like selectors which nonetheless don't -follow the <tt>init</tt> conventions. Typically these are either -accidental naming collisions or helper methods called during -initialization. Because of the peculiar retain/release behavior -of <tt>init</tt> methods, it's very important not to treat these -methods as <tt>init</tt> methods if they aren't meant to be. It was -felt that implicitly defining these methods out of the family based on -the exact relationship between the return type and the declaring class -would be much too subtle and fragile. Therefore we identify a small -number of legitimate-seeming return types and call everything else an -error. This serves the secondary purpose of encouraging programmers -not to accidentally give methods names in the <tt>init</tt> family.</p> - -<p>Note that a method with an <tt>init</tt>-family selector which -returns a non-Objective-C type (e.g. <tt>void</tt>) is perfectly -well-formed; it simply isn't in the <tt>init</tt> family.</p></div> -</li> -</ul> - -<p>A program is ill-formed if a method's declarations, -implementations, and overrides do not all have the same method -family.</p> - -<div id="family.attribute"> -<h1>Explicit method family control</h1> - -<p>A method may be annotated with the <tt>objc_method_family</tt> -attribute to precisely control which method family it belongs to. If -a method in an <tt>@implementation</tt> does not have this attribute, -but there is a method declared in the corresponding <tt>@interface</tt> -that does, then the attribute is copied to the declaration in the -<tt>@implementation</tt>. The attribute is available outside of ARC, -and may be tested for with the preprocessor query -<tt>__has_attribute(objc_method_family)</tt>.</p> - -<p>The attribute is spelled -<tt>__attribute__((objc_method_family(<i>family</i>)))</tt>. -If <i>family</i> is <tt>none</tt>, the method has no family, even if -it would otherwise be considered to have one based on its selector and -type. Otherwise, <i>family</i> must be one -of <tt>alloc</tt>, <tt>copy</tt>, <tt>init</tt>, -<tt>mutableCopy</tt>, or <tt>new</tt>, in which case the method is -considered to belong to the corresponding family regardless of its -selector. It is an error if a method that is explicitly added to a -family in this way does not meet the requirements of the family other -than the selector naming convention.</p> - -<div class="rationale"><p>Rationale: the rules codified in this document -describe the standard conventions of Objective-C. However, as these -conventions have not heretofore been enforced by an unforgiving -mechanical system, they are only imperfectly kept, especially as they -haven't always even been precisely defined. While it is possible to -define low-level ownership semantics with attributes like -<tt>ns_returns_retained</tt>, this attribute allows the user to -communicate semantic intent, which is of use both to ARC (which, e.g., -treats calls to <tt>init</tt> specially) and the static analyzer.</p></div> -</div> - -<div id="family.semantics"> -<h1>Semantics of method families</h1> - -<p>A method's membership in a method family may imply non-standard -semantics for its parameters and return type.</p> - -<p>Methods in the <tt>alloc</tt>, <tt>copy</tt>, <tt>mutableCopy</tt>, -and <tt>new</tt> families — that is, methods in all the -currently-defined families except <tt>init</tt> — implicitly -<a href="#objects.operands.retained_returns">return a retained -object</a> as if they were annotated with -the <tt>ns_returns_retained</tt> attribute. This can be overridden by -annotating the method with either of -the <tt>ns_returns_autoreleased</tt> or -<tt>ns_returns_not_retained</tt> attributes.</p> - -<p>Properties also follow same naming rules as methods. This means that -those in the <tt>alloc</tt>, <tt>copy</tt>, <tt>mutableCopy</tt>, -and <tt>new</tt> families provide access to -<a href="#objects.operands.retained_returns">retained objects</a>. -This can be overridden by annotating the property with -<tt>ns_returns_not_retained</tt> attribute.</p> - -<div id="family.semantics.init"> -<h1>Semantics of <tt>init</tt></h1> -<p>Methods in the <tt>init</tt> family implicitly -<a href="#objects.operands.consumed">consume</a> their <tt>self</tt> -parameter and <a href="#objects.operands.retained_returns">return a -retained object</a>. Neither of these properties can be altered -through attributes.</p> - -<p>A call to an <tt>init</tt> method with a receiver that is either -<tt>self</tt> (possibly parenthesized or casted) or <tt>super</tt> is -called a <span class="term">delegate init call</span>. It is an error -for a delegate init call to be made except from an <tt>init</tt> -method, and excluding blocks within such methods.</p> - -<p>As an exception to the <a href="misc.self">usual rule</a>, the -variable <tt>self</tt> is mutable in an <tt>init</tt> method and has -the usual semantics for a <tt>__strong</tt> variable. However, it is -undefined behavior and the program is ill-formed, no diagnostic -required, if an <tt>init</tt> method attempts to use the previous -value of <tt>self</tt> after the completion of a delegate init call. -It is conventional, but not required, for an <tt>init</tt> method to -return <tt>self</tt>.</p> - -<p>It is undefined behavior for a program to cause two or more calls -to <tt>init</tt> methods on the same object, except that -each <tt>init</tt> method invocation may perform at most one delegate -init call.</p> - -</div> <!-- family.semantics.init --> - -<div id="family.semantics.result_type"> -<h1>Related result types</h1> - -<p>Certain methods are candidates to have <span class="term">related -result types</span>:</p> -<ul> -<li>class methods in the <tt>alloc</tt> and <tt>new</tt> method families</li> -<li>instance methods in the <tt>init</tt> family</li> -<li>the instance method <tt>self</tt></li> -<li>outside of ARC, the instance methods <tt>retain</tt> and <tt>autorelease</tt></li> -</ul> - -<p>If the formal result type of such a method is <tt>id</tt> or -protocol-qualified <tt>id</tt>, or a type equal to the declaring class -or a superclass, then it is said to have a related result type. In -this case, when invoked in an explicit message send, it is assumed to -return a type related to the type of the receiver:</p> - -<ul> -<li>if it is a class method, and the receiver is a class -name <tt>T</tt>, the message send expression has type <tt>T*</tt>; -otherwise</li> -<li>if it is an instance method, and the receiver has type <tt>T</tt>, -the message send expression has type <tt>T</tt>; otherwise</li> -<li>the message send expression has the normal result type of the -method.</li> -</ul> - -<p>This is a new rule of the Objective-C language and applies outside -of ARC.</p> - -<div class="rationale"><p>Rationale: ARC's automatic code emission is -more prone than most code to signature errors, i.e. errors where a -call was emitted against one method signature, but the implementing -method has an incompatible signature. Having more precise type -information helps drastically lower this risk, as well as catching -a number of latent bugs.</p></div> - -</div> <!-- family.semantics.result_type --> -</div> <!-- family.semantics --> -</div> <!-- family --> - -<div id="optimization"> -<h1>Optimization</h1> - -<p>ARC applies aggressive rules for the optimization of local -behavior. These rules are based around a core assumption of -<span class="term">local balancing</span>: that other code will -perform retains and releases as necessary (and only as necessary) for -its own safety, and so the optimizer does not need to consider global -properties of the retain and release sequence. For example, if a -retain and release immediately bracket a call, the optimizer can -delete the retain and release on the assumption that the called -function will not do a constant number of unmotivated releases -followed by a constant number of <q>balancing</q> retains, such that -the local retain/release pair is the only thing preventing the called -function from ending up with a dangling reference.</p> - -<p>The optimizer assumes that when a new value enters local control, -e.g. from a load of a non-local object or as the result of a function -call, it is instaneously valid. Subsequently, a retain and release of -a value are necessary on a computation path only if there is a use of -that value before the release and after any operation which might -cause a release of the value (including indirectly or non-locally), -and only if the value is not demonstrably already retained.</p> - -<p>The complete optimization rules are quite complicated, but it would -still be useful to document them here.</p> - -<div id="optimization.precise"> -<h1>Precise lifetime semantics</h1> - -<p>In general, ARC maintains an invariant that a retainable object -pointer held in a <tt>__strong</tt> object will be retained for the -full formal lifetime of the object. Objects subject to this invariant -have <span class="term">precise lifetime semantics</span>.</p> - -<p>By default, local variables of automatic storage duration do not -have precise lifetime semantics. Such objects are simply strong -references which hold values of retainable object pointer type, and -these values are still fully subject to the optimizations on values -under local control.</p> - -<div class="rationale"><p>Rationale: applying these precise-lifetime -semantics strictly would be prohibitive. Many useful optimizations -that might theoretically decrease the lifetime of an object would be -rendered impossible. Essentially, it promises too much.</p></div> - -<p>A local variable of retainable object owner type and automatic -storage duration may be annotated with the <tt>objc_precise_lifetime</tt> -attribute to indicate that it should be considered to be an object -with precise lifetime semantics.</p> - -<div class="rationale"><p>Rationale: nonetheless, it is sometimes -useful to be able to force an object to be released at a precise time, -even if that object does not appear to be used. This is likely to be -uncommon enough that the syntactic weight of explicitly requesting -these semantics will not be burdensome, and may even make the code -clearer.</p></div> - -</div> <!-- optimization.precise --> - -</div> <!-- optimization --> - -<div id="misc"> -<h1>Miscellaneous</h1> - -<div id="misc.special_methods"> -<h1>Special methods</h1> - -<div id="misc.special_methods.retain"> -<h1>Memory management methods</h1> - -<p>A program is ill-formed if it contains a method definition, message -send, or <tt>@selector</tt> expression for any of the following -selectors:</p> -<ul> -<li><tt>autorelease</tt></li> -<li><tt>release</tt></li> -<li><tt>retain</tt></li> -<li><tt>retainCount</tt></li> -</ul> - -<div class="rationale"><p>Rationale: <tt>retainCount</tt> is banned -because ARC robs it of consistent semantics. The others were banned -after weighing three options for how to deal with message sends:</p> - -<p><b>Honoring</b> them would work out very poorly if a programmer -naively or accidentally tried to incorporate code written for manual -retain/release code into an ARC program. At best, such code would do -twice as much work as necessary; quite frequently, however, ARC and -the explicit code would both try to balance the same retain, leading -to crashes. The cost is losing the ability to perform <q>unrooted</q> -retains, i.e. retains not logically corresponding to a strong -reference in the object graph.</p> - -<p><b>Ignoring</b> them would badly violate user expectations about their -code. While it <em>would</em> make it easier to develop code simultaneously -for ARC and non-ARC, there is very little reason to do so except for -certain library developers. ARC and non-ARC translation units share -an execution model and can seamlessly interoperate. Within a -translation unit, a developer who faithfully maintains their code in -non-ARC mode is suffering all the restrictions of ARC for zero -benefit, while a developer who isn't testing the non-ARC mode is -likely to be unpleasantly surprised if they try to go back to it.</p> - -<p><b>Banning</b> them has the disadvantage of making it very awkward -to migrate existing code to ARC. The best answer to that, given a -number of other changes and restrictions in ARC, is to provide a -specialized tool to assist users in that migration.</p> - -<p>Implementing these methods was banned because they are too integral -to the semantics of ARC; many tricks which worked tolerably under -manual reference counting will misbehave if ARC performs an ephemeral -extra retain or two. If absolutely required, it is still possible to -implement them in non-ARC code, for example in a category; the -implementations must obey the <a href="#objects.retains">semantics</a> -laid out elsewhere in this document.</p> - -</div> -</div> <!-- misc.special_methods.retain --> - -<div id="misc.special_methods.dealloc"> -<h1><tt>dealloc</tt></h1> - -<p>A program is ill-formed if it contains a message send -or <tt>@selector</tt> expression for the selector <tt>dealloc</tt>.</p> - -<div class="rationale"><p>Rationale: there are no legitimate reasons -to call <tt>dealloc</tt> directly.</p></div> - -<p>A class may provide a method definition for an instance method -named <tt>dealloc</tt>. This method will be called after the final -<tt>release</tt> of the object but before it is deallocated or any of -its instance variables are destroyed. The superclass's implementation -of <tt>dealloc</tt> will be called automatically when the method -returns.</p> - -<div class="rationale"><p>Rationale: even though ARC destroys instance -variables automatically, there are still legitimate reasons to write -a <tt>dealloc</tt> method, such as freeing non-retainable resources. -Failing to call <tt>[super dealloc]</tt> in such a method is nearly -always a bug. Sometimes, the object is simply trying to prevent -itself from being destroyed, but <tt>dealloc</tt> is really far too -late for the object to be raising such objections. Somewhat more -legitimately, an object may have been pool-allocated and should not be -deallocated with <tt>free</tt>; for now, this can only be supported -with a <tt>dealloc</tt> implementation outside of ARC. Such an -implementation must be very careful to do all the other work -that <tt>NSObject</tt>'s <tt>dealloc</tt> would, which is outside the -scope of this document to describe.</p></div> - -<p>The instance variables for an ARC-compiled class will be destroyed -at some point after control enters the <tt>dealloc</tt> method for the -root class of the class. The ordering of the destruction of instance -variables is unspecified, both within a single class and between -subclasses and superclasses.</p> - -<div class="rationale"><p>Rationale: the traditional, non-ARC pattern -for destroying instance variables is to destroy them immediately -before calling <tt>[super dealloc]</tt>. Unfortunately, message -sends from the superclass are quite capable of reaching methods in the -subclass, and those methods may well read or write to those instance -variables. Making such message sends from dealloc is generally -discouraged, since the subclass may well rely on other invariants that -were broken during <tt>dealloc</tt>, but it's not so inescapably -dangerous that we felt comfortable calling it undefined behavior. -Therefore we chose to delay destroying the instance variables to a -point at which message sends are clearly disallowed: the point at -which the root class's deallocation routines take over.</p> - -<p>In most code, the difference is not observable. It can, however, -be observed if an instance variable holds a strong reference to an -object whose deallocation will trigger a side-effect which must be -carefully ordered with respect to the destruction of the super class. -Such code violates the design principle that semantically important -behavior should be explicit. A simple fix is to clear the instance -variable manually during <tt>dealloc</tt>; a more holistic solution is -to move semantically important side-effects out of -<tt>dealloc</tt> and into a separate teardown phase which can rely on -working with well-formed objects.</p></div> - -</div> - -</div> <!-- misc.special_methods --> - -<div id="autoreleasepool"> -<h1><tt>@autoreleasepool</tt></h1> - -<p>To simplify the use of autorelease pools, and to bring them under -the control of the compiler, a new kind of statement is available in -Objective-C. It is written <tt>@autoreleasepool</tt> followed by -a <i>compound-statement</i>, i.e. by a new scope delimited by curly -braces. Upon entry to this block, the current state of the -autorelease pool is captured. When the block is exited normally, -whether by fallthrough or directed control flow (such -as <tt>return</tt> or <tt>break</tt>), the autorelease pool is -restored to the saved state, releasing all the objects in it. When -the block is exited with an exception, the pool is not drained.</p> - -<p><tt>@autoreleasepool</tt> may be used in non-ARC translation units, -with equivalent semantics.</p> - -<p>A program is ill-formed if it refers to the -<tt>NSAutoreleasePool</tt> class.</p> - -<div class="rationale"><p>Rationale: autorelease pools are clearly -important for the compiler to reason about, but it is far too much to -expect the compiler to accurately reason about control dependencies -between two calls. It is also very easy to accidentally forget to -drain an autorelease pool when using the manual API, and this can -significantly inflate the process's high-water-mark. The introduction -of a new scope is unfortunate but basically required for sane -interaction with the rest of the language. Not draining the pool -during an unwind is apparently required by the Objective-C exceptions -implementation.</p></div> - -</div> <!-- autoreleasepool --> - -<div id="misc.self"> -<h1><tt>self</tt></h1> - -<p>The <tt>self</tt> parameter variable of an Objective-C method is -never actually retained by the implementation. It is undefined -behavior, or at least dangerous, to cause an object to be deallocated -during a message send to that object.</p> - -<p>To make this safe, for Objective-C instance methods <tt>self</tt> is -implicitly <tt>const</tt> unless the method is in the <a -href="#family.semantics.init"><tt>init</tt> family</a>. Further, <tt>self</tt> -is <b>always</b> implicitly <tt>const</tt> within a class method.</p> - -<div class="rationale"><p>Rationale: the cost of -retaining <tt>self</tt> in all methods was found to be prohibitive, as -it tends to be live across calls, preventing the optimizer from -proving that the retain and release are unnecessary — for good -reason, as it's quite possible in theory to cause an object to be -deallocated during its execution without this retain and release. -Since it's extremely uncommon to actually do so, even unintentionally, -and since there's no natural way for the programmer to remove this -retain/release pair otherwise (as there is for other parameters by, -say, making the variable <tt>__unsafe_unretained</tt>), we chose to -make this optimizing assumption and shift some amount of risk to the -user.</p></div> - -</div> <!-- misc.self --> - -<div id="misc.enumeration"> -<h1>Fast enumeration iteration variables</h1> - -<p>If a variable is declared in the condition of an Objective-C fast -enumeration loop, and the variable has no explicit ownership -qualifier, then it is qualified with <tt>const __strong</tt> and -objects encountered during the enumeration are not actually -retained.</p> - -<div class="rationale"><p>Rationale: this is an optimization made -possible because fast enumeration loops promise to keep the objects -retained during enumeration, and the collection itself cannot be -synchronously modified. It can be overridden by explicitly qualifying -the variable with <tt>__strong</tt>, which will make the variable -mutable again and cause the loop to retain the objects it -encounters.</p></div> - -</div> <!-- misc.enumeration --> - -<div id="misc.blocks"> -<h1>Blocks</h1> - -<p>The implicit <tt>const</tt> capture variables created when -evaluating a block literal expression have the same ownership -semantics as the local variables they capture. The capture is -performed by reading from the captured variable and initializing the -capture variable with that value; the capture variable is destroyed -when the block literal is, i.e. at the end of the enclosing scope.</p> - -<p>The <a href="#ownership.inference">inference</a> rules apply -equally to <tt>__block</tt> variables, which is a shift in semantics -from non-ARC, where <tt>__block</tt> variables did not implicitly -retain during capture.</p> - -<p><tt>__block</tt> variables of retainable object owner type are -moved off the stack by initializing the heap copy with the result of -moving from the stack copy.</p> - -<p>With the exception of retains done as part of initializing -a <tt>__strong</tt> parameter variable or reading a <tt>__weak</tt> -variable, whenever these semantics call for retaining a value of -block-pointer type, it has the effect of a <tt>Block_copy</tt>. The -optimizer may remove such copies when it sees that the result is -used only as an argument to a call.</p> - -</div> <!-- misc.blocks --> - -<div id="misc.exceptions"> -<h1>Exceptions</h1> - -<p>By default in Objective C, ARC is not exception-safe for normal -releases:</p> -<ul> -<li>It does not end the lifetime of <tt>__strong</tt> variables when -their scopes are abnormally terminated by an exception.</li> -<li>It does not perform releases which would occur at the end of -a full-expression if that full-expression throws an exception.</li> -</ul> - -<p>A program may be compiled with the option -<tt>-fobjc-arc-exceptions</tt> in order to enable these, or with the -option <tt>-fno-objc-arc-exceptions</tt> to explicitly disable them, -with the last such argument <q>winning</q>.</p> - -<div class="rationale"><p>Rationale: the standard Cocoa convention is -that exceptions signal programmer error and are not intended to be -recovered from. Making code exceptions-safe by default would impose -severe runtime and code size penalties on code that typically does not -actually care about exceptions safety. Therefore, ARC-generated code -leaks by default on exceptions, which is just fine if the process is -going to be immediately terminated anyway. Programs which do care -about recovering from exceptions should enable the option.</p></div> - -<p>In Objective-C++, <tt>-fobjc-arc-exceptions</tt> is enabled by -default.</p> - -<div class="rationale"><p>Rationale: C++ already introduces pervasive -exceptions-cleanup code of the sort that ARC introduces. C++ -programmers who have not already disabled exceptions are much more -likely to actual require exception-safety.</p></div> - -<p>ARC does end the lifetimes of <tt>__weak</tt> objects when an -exception terminates their scope unless exceptions are disabled in the -compiler.</p> - -<div class="rationale"><p>Rationale: the consequence of a -local <tt>__weak</tt> object not being destroyed is very likely to be -corruption of the Objective-C runtime, so we want to be safer here. -Of course, potentially massive leaks are about as likely to take down -the process as this corruption is if the program does try to recover -from exceptions.</p></div> - -</div> <!-- misc.exceptions --> - -<div id="misc.interior"> -<h1>Interior pointers</h1> - -<p>An Objective-C method returning a non-retainable pointer may be -annotated with the <tt>objc_returns_inner_pointer</tt> attribute to -indicate that it returns a handle to the internal data of an object, -and that this reference will be invalidated if the object is -destroyed. When such a message is sent to an object, the object's -lifetime will be extended until at least the earliest of:</p> - -<ul> -<li>the last use of the returned pointer, or any pointer derived from -it, in the calling function or</li> -<li>the autorelease pool is restored to a previous state.</li> -</ul> - -<div class="rationale"><p>Rationale: not all memory and resources are -managed with reference counts; it is common for objects to manage -private resources in their own, private way. Typically these -resources are completely encapsulated within the object, but some -classes offer their users direct access for efficiency. If ARC is not -aware of methods that return such <q>interior</q> pointers, its -optimizations can cause the owning object to be reclaimed too soon. -This attribute informs ARC that it must tread lightly.</p> - -<p>The extension rules are somewhat intentionally vague. The -autorelease pool limit is there to permit a simple implementation to -simply retain and autorelease the receiver. The other limit permits -some amount of optimization. The phrase <q>derived from</q> is -intended to encompass the results both of pointer transformations, -such as casts and arithmetic, and of loading from such derived -pointers; furthermore, it applies whether or not such derivations are -applied directly in the calling code or by other utility code (for -example, the C library routine <tt>strchr</tt>). However, the -implementation never need account for uses after a return from the -code which calls the method returning an interior pointer.</p></div> - -<p>As an exception, no extension is required if the receiver is loaded -directly from a <tt>__strong</tt> object -with <a href="#optimization.precise">precise lifetime semantics</a>.</p> - -<div class="rationale"><p>Rationale: implicit autoreleases carry the -risk of significantly inflating memory use, so it's important to -provide users a way of avoiding these autoreleases. Tying this to -precise lifetime semantics is ideal, as for local variables this -requires a very explicit annotation, which allows ARC to trust the -user with good cheer.</p></div> - -</div> <!-- misc.interior --> - -<div id="misc.c-retainable"> -<h1>C retainable pointer types</h1> - -<p>A type is a <span class="term">C retainable pointer type</span> -if it is a pointer to (possibly qualified) <tt>void</tt> or a -pointer to a (possibly qualifier) <tt>struct</tt> or <tt>class</tt> -type.</p> - -<div class="rationale"><p>Rationale: ARC does not manage pointers of -CoreFoundation type (or any of the related families of retainable C -pointers which interoperate with Objective-C for retain/release -operation). In fact, ARC does not even know how to distinguish these -types from arbitrary C pointer types. The intent of this concept is -to filter out some obviously non-object types while leaving a hook for -later tightening if a means of exhaustively marking CF types is made -available.</p></div> - -<div id="misc.c-retainable.audit"> -<h1>Auditing of C retainable pointer interfaces</h1> - -<p><span class="revision"><span class="whenRevised">[beginning Apple 4.0, LLVM 3.1]</span></span></p> - -<p>A C function may be marked with the <tt>cf_audited_transfer</tt> -attribute to express that, except as otherwise marked with attributes, -it obeys the parameter (consuming vs. non-consuming) and return -(retained vs. non-retained) conventions for a C function of its name, -namely:</p> - -<ul> -<li>A parameter of C retainable pointer type is assumed to not be -consumed unless it is marked with the <tt>cf_consumed</tt> attribute, and</li> -<li>A result of C retainable pointer type is assumed to not be -returned retained unless the function is either -marked <tt>cf_returns_retained</tt> or it follows -the create/copy naming convention and is not -marked <tt>cf_returns_not_retained</tt>.</li> -</ul> - -<p>A function obeys the <span class="term">create/copy</span> naming -convention if its name contains as a substring:</p> -<ul> -<li>either <q>Create</q> or <q>Copy</q> not followed by a lowercase letter, or</li> -<li>either <q>create</q> or <q>copy</q> not followed by a lowercase -letter and not preceded by any letter, whether uppercase or lowercase.</li> -</ul> - -<p>A second attribute, <tt>cf_unknown_transfer</tt>, signifies that a -function's transfer semantics cannot be accurately captured using any -of these annotations. A program is ill-formed if it annotates the -same function with both <tt>cf_audited_transfer</tt> -and <tt>cf_unknown_transfer</tt>.</p> - -<p>A pragma is provided to facilitate the mass annotation of interfaces:</p> - -<pre>#pragma clang arc_cf_code_audited begin -... -#pragma clang arc_cf_code_audited end</pre> - -<p>All C functions declared within the extent of this pragma are -treated as if annotated with the <tt>cf_audited_transfer</tt> -attribute unless they otherwise have the <tt>cf_unknown_transfer</tt> -attribute. The pragma is accepted in all language modes. A program -is ill-formed if it attempts to change files, whether by including a -file or ending the current file, within the extent of this pragma.</p> - -<p>It is possible to test for all the features in this section with -<tt>__has_feature(arc_cf_code_audited)</tt>.</p> - -<div class="rationale"><p>Rationale: A significant inconvenience in -ARC programming is the necessity of interacting with APIs based around -C retainable pointers. These features are designed to make it -relatively easy for API authors to quickly review and annotate their -interfaces, in turn improving the fidelity of tools such as the static -analyzer and ARC. The single-file restriction on the pragma is -designed to eliminate the risk of accidentally annotating some other -header's interfaces.</p></div> - -</div> <!-- misc.c-retainable.audit --> - -</div> <!-- misc.c-retainable --> - -</div> <!-- misc --> - -<div id="runtime"> -<h1>Runtime support</h1> - -<p>This section describes the interaction between the ARC runtime and -the code generated by the ARC compiler. This is not part of the ARC -language specification; instead, it is effectively a language-specific -ABI supplement, akin to the <q>Itanium</q> generic ABI for C++.</p> - -<p>Ownership qualification does not alter the storage requirements for -objects, except that it is undefined behavior if a <tt>__weak</tt> -object is inadequately aligned for an object of type <tt>id</tt>. The -other qualifiers may be used on explicitly under-aligned memory.</p> - -<p>The runtime tracks <tt>__weak</tt> objects which holds non-null -values. It is undefined behavior to direct modify a <tt>__weak</tt> -object which is being tracked by the runtime except through an -<a href="#runtime.objc_storeWeak"><tt>objc_storeWeak</tt></a>, -<a href="#runtime.objc_destroyWeak"><tt>objc_destroyWeak</tt></a>, -or <a href="#runtime.objc_moveWeak"><tt>objc_moveWeak</tt></a> -call.</p> - -<p>The runtime must provide a number of new entrypoints which the -compiler may emit, which are described in the remainder of this -section.</p> - -<div class="rationale"><p>Rationale: Several of these functions are -semantically equivalent to a message send; we emit calls to C -functions instead because:</p> -<ul> -<li>the machine code to do so is significantly smaller,</li> -<li>it is much easier to recognize the C functions in the ARC optimizer, and</li> -<li>a sufficient sophisticated runtime may be able to avoid the -message send in common cases.</li> -</ul> - -<p>Several other of these functions are <q>fused</q> operations which -can be described entirely in terms of other operations. We use the -fused operations primarily as a code-size optimization, although in -some cases there is also a real potential for avoiding redundant -operations in the runtime.</p> - -</div> - -<div id="runtime.objc_autorelease"> -<h1><tt>id objc_autorelease(id value);</tt></h1> -<p><i>Precondition:</i> <tt>value</tt> is null or a pointer to a -valid object.</p> -<p>If <tt>value</tt> is null, this call has no effect. Otherwise, it -adds the object to the innermost autorelease pool exactly as if the -object had been sent the <tt>autorelease</tt> message.</p> -<p>Always returns <tt>value</tt>.</p> -</div> <!-- runtime.objc_autorelease --> - -<div id="runtime.objc_autoreleasePoolPop"> -<h1><tt>void objc_autoreleasePoolPop(void *pool);</tt></h1> -<p><i>Precondition:</i> <tt>pool</tt> is the result of a previous call to -<a href="runtime.objc_autoreleasePoolPush"><tt>objc_autoreleasePoolPush</tt></a> -on the current thread, where neither <tt>pool</tt> nor any enclosing -pool have previously been popped.</p> -<p>Releases all the objects added to the given autorelease pool and -any autorelease pools it encloses, then sets the current autorelease -pool to the pool directly enclosing <tt>pool</tt>.</p> -</div> <!-- runtime.objc_autoreleasePoolPop --> - -<div id="runtime.objc_autoreleasePoolPush"> -<h1><tt>void *objc_autoreleasePoolPush(void);</tt></h1> -<p>Creates a new autorelease pool that is enclosed by the current -pool, makes that the current pool, and returns an opaque <q>handle</q> -to it.</p> - -<div class="rationale"><p>Rationale: while the interface is described -as an explicit hierarchy of pools, the rules allow the implementation -to just keep a stack of objects, using the stack depth as the opaque -pool handle.</p></div> - -</div> <!-- runtime.objc_autoreleasePoolPush --> - -<div id="runtime.objc_autoreleaseReturnValue"> -<h1><tt>id objc_autoreleaseReturnValue(id value);</tt></h1> -<p><i>Precondition:</i> <tt>value</tt> is null or a pointer to a -valid object.</p> -<p>If <tt>value</tt> is null, this call has no effect. Otherwise, it -makes a best effort to hand off ownership of a retain count on the -object to a call -to <a href="runtime.objc_retainAutoreleasedReturnValue"><tt>objc_retainAutoreleasedReturnValue</tt></a> -for the same object in an enclosing call frame. If this is not -possible, the object is autoreleased as above.</p> -<p>Always returns <tt>value</tt>.</p> -</div> <!-- runtime.objc_autoreleaseReturnValue --> - -<div id="runtime.objc_copyWeak"> -<h1><tt>void objc_copyWeak(id *dest, id *src);</tt></h1> -<p><i>Precondition:</i> <tt>src</tt> is a valid pointer which either -contains a null pointer or has been registered as a <tt>__weak</tt> -object. <tt>dest</tt> is a valid pointer which has not been -registered as a <tt>__weak</tt> object.</p> -<p><tt>dest</tt> is initialized to be equivalent to <tt>src</tt>, -potentially registering it with the runtime. Equivalent to the -following code:</p> -<pre>void objc_copyWeak(id *dest, id *src) { - objc_release(objc_initWeak(dest, objc_loadWeakRetained(src))); -}</pre> -<p>Must be atomic with respect to calls to <tt>objc_storeWeak</tt> -on <tt>src</tt>.</p> -</div> <!-- runtime.objc_copyWeak --> - -<div id="runtime.objc_destroyWeak"> -<h1><tt>void objc_destroyWeak(id *object);</tt></h1> -<p><i>Precondition:</i> <tt>object</tt> is a valid pointer which -either contains a null pointer or has been registered as -a <tt>__weak</tt> object.</p> -<p><tt>object</tt> is unregistered as a weak object, if it ever was. -The current value of <tt>object</tt> is left unspecified; otherwise, -equivalent to the following code:</p> -<pre>void objc_destroyWeak(id *object) { - objc_storeWeak(object, nil); -}</pre> -<p>Does not need to be atomic with respect to calls -to <tt>objc_storeWeak</tt> on <tt>object</tt>.</p> -</div> <!-- runtime.objc_destroyWeak --> - -<div id="runtime.objc_initWeak"> -<h1><tt>id objc_initWeak(id *object, id value);</tt></h1> -<p><i>Precondition:</i> <tt>object</tt> is a valid pointer which has -not been registered as a <tt>__weak</tt> object. <tt>value</tt> is -null or a pointer to a valid object.</p> -<p>If <tt>value</tt> is a null pointer or the object to which it -points has begun deallocation, <tt>object</tt> is zero-initialized. -Otherwise, <tt>object</tt> is registered as a <tt>__weak</tt> object -pointing to <tt>value</tt>. Equivalent to the following code:</p> -<pre>id objc_initWeak(id *object, id value) { - *object = nil; - return objc_storeWeak(object, value); -}</pre> -<p>Returns the value of <tt>object</tt> after the call.</p> -<p>Does not need to be atomic with respect to calls -to <tt>objc_storeWeak</tt> on <tt>object</tt>.</p> -</div> <!-- runtime.objc_initWeak --> - -<div id="runtime.objc_loadWeak"> -<h1><tt>id objc_loadWeak(id *object);</tt></h1> -<p><i>Precondition:</i> <tt>object</tt> is a valid pointer which -either contains a null pointer or has been registered as -a <tt>__weak</tt> object.</p> -<p>If <tt>object</tt> is registered as a <tt>__weak</tt> object, and -the last value stored into <tt>object</tt> has not yet been -deallocated or begun deallocation, retains and autoreleases that value -and returns it. Otherwise returns null. Equivalent to the following -code:</p> -<pre>id objc_loadWeak(id *object) { - return objc_autorelease(objc_loadWeakRetained(object)); -}</pre> -<p>Must be atomic with respect to calls to <tt>objc_storeWeak</tt> -on <tt>object</tt>.</p> -<div class="rationale">Rationale: loading weak references would be -inherently prone to race conditions without the retain.</div> -</div> <!-- runtime.objc_loadWeak --> - -<div id="runtime.objc_loadWeakRetained"> -<h1><tt>id objc_loadWeakRetained(id *object);</tt></h1> -<p><i>Precondition:</i> <tt>object</tt> is a valid pointer which -either contains a null pointer or has been registered as -a <tt>__weak</tt> object.</p> -<p>If <tt>object</tt> is registered as a <tt>__weak</tt> object, and -the last value stored into <tt>object</tt> has not yet been -deallocated or begun deallocation, retains that value and returns it. -Otherwise returns null.</p> -<p>Must be atomic with respect to calls to <tt>objc_storeWeak</tt> -on <tt>object</tt>.</p> -</div> <!-- runtime.objc_loadWeakRetained --> - -<div id="runtime.objc_moveWeak"> -<h1><tt>void objc_moveWeak(id *dest, id *src);</tt></h1> -<p><i>Precondition:</i> <tt>src</tt> is a valid pointer which either -contains a null pointer or has been registered as a <tt>__weak</tt> -object. <tt>dest</tt> is a valid pointer which has not been -registered as a <tt>__weak</tt> object.</p> -<p><tt>dest</tt> is initialized to be equivalent to <tt>src</tt>, -potentially registering it with the runtime. <tt>src</tt> may then be -left in its original state, in which case this call is equivalent -to <a href="#runtime.objc_copyWeak"><tt>objc_copyWeak</tt></a>, or it -may be left as null.</p> -<p>Must be atomic with respect to calls to <tt>objc_storeWeak</tt> -on <tt>src</tt>.</p> -</div> <!-- runtime.objc_moveWeak --> - -<div id="runtime.objc_release"> -<h1><tt>void objc_release(id value);</tt></h1> -<p><i>Precondition:</i> <tt>value</tt> is null or a pointer to a -valid object.</p> -<p>If <tt>value</tt> is null, this call has no effect. Otherwise, it -performs a release operation exactly as if the object had been sent -the <tt>release</tt> message.</p> -</div> <!-- runtime.objc_release --> - -<div id="runtime.objc_retain"> -<h1><tt>id objc_retain(id value);</tt></h1> -<p><i>Precondition:</i> <tt>value</tt> is null or a pointer to a -valid object.</p> -<p>If <tt>value</tt> is null, this call has no effect. Otherwise, it -performs a retain operation exactly as if the object had been sent -the <tt>retain</tt> message.</p> -<p>Always returns <tt>value</tt>.</p> -</div> <!-- runtime.objc_retain --> - -<div id="runtime.objc_retainAutorelease"> -<h1><tt>id objc_retainAutorelease(id value);</tt></h1> -<p><i>Precondition:</i> <tt>value</tt> is null or a pointer to a -valid object.</p> -<p>If <tt>value</tt> is null, this call has no effect. Otherwise, it -performs a retain operation followed by an autorelease operation. -Equivalent to the following code:</p> -<pre>id objc_retainAutorelease(id value) { - return objc_autorelease(objc_retain(value)); -}</pre> -<p>Always returns <tt>value</tt>.</p> -</div> <!-- runtime.objc_retainAutorelease --> - -<div id="runtime.objc_retainAutoreleaseReturnValue"> -<h1><tt>id objc_retainAutoreleaseReturnValue(id value);</tt></h1> -<p><i>Precondition:</i> <tt>value</tt> is null or a pointer to a -valid object.</p> -<p>If <tt>value</tt> is null, this call has no effect. Otherwise, it -performs a retain operation followed by the operation described in -<a href="#runtime.objc_autoreleaseReturnValue"><tt>objc_autoreleaseReturnValue</tt></a>. -Equivalent to the following code:</p> -<pre>id objc_retainAutoreleaseReturnValue(id value) { - return objc_autoreleaseReturnValue(objc_retain(value)); -}</pre> -<p>Always returns <tt>value</tt>.</p> -</div> <!-- runtime.objc_retainAutoreleaseReturnValue --> - -<div id="runtime.objc_retainAutoreleasedReturnValue"> -<h1><tt>id objc_retainAutoreleasedReturnValue(id value);</tt></h1> -<p><i>Precondition:</i> <tt>value</tt> is null or a pointer to a -valid object.</p> -<p>If <tt>value</tt> is null, this call has no effect. Otherwise, it -attempts to accept a hand off of a retain count from a call to -<a href="#runtime.objc_autoreleaseReturnValue"><tt>objc_autoreleaseReturnValue</tt></a> -on <tt>value</tt> in a recently-called function or something it -calls. If that fails, it performs a retain operation exactly -like <a href="#runtime.objc_retain"><tt>objc_retain</tt></a>.</p> -<p>Always returns <tt>value</tt>.</p> -</div> <!-- runtime.objc_retainAutoreleasedReturnValue --> - -<div id="runtime.objc_retainBlock"> -<h1><tt>id objc_retainBlock(id value);</tt></h1> -<p><i>Precondition:</i> <tt>value</tt> is null or a pointer to a -valid block object.</p> -<p>If <tt>value</tt> is null, this call has no effect. Otherwise, if -the block pointed to by <tt>value</tt> is still on the stack, it is -copied to the heap and the address of the copy is returned. Otherwise -a retain operation is performed on the block exactly as if it had been -sent the <tt>retain</tt> message.</p> -</div> <!-- runtime.objc_retainBlock --> - -<div id="runtime.objc_storeStrong"> -<h1><tt>id objc_storeStrong(id *object, id value);</tt></h1> -<p><i>Precondition:</i> <tt>object</tt> is a valid pointer to -a <tt>__strong</tt> object which is adequately aligned for a -pointer. <tt>value</tt> is null or a pointer to a valid object.</p> -<p>Performs the complete sequence for assigning to a <tt>__strong</tt> -object of non-block type. Equivalent to the following code:</p> -<pre>id objc_storeStrong(id *object, id value) { - value = [value retain]; - id oldValue = *object; - *object = value; - [oldValue release]; - return value; -}</pre> -<p>Always returns <tt>value</tt>.</p> -</div> <!-- runtime.objc_storeStrong --> - -<div id="runtime.objc_storeWeak"> -<h1><tt>id objc_storeWeak(id *object, id value);</tt></h1> -<p><i>Precondition:</i> <tt>object</tt> is a valid pointer which -either contains a null pointer or has been registered as -a <tt>__weak</tt> object. <tt>value</tt> is null or a pointer to a -valid object.</p> -<p>If <tt>value</tt> is a null pointer or the object to which it -points has begun deallocation, <tt>object</tt> is assigned null -and unregistered as a <tt>__weak</tt> object. Otherwise, -<tt>object</tt> is registered as a <tt>__weak</tt> object or has its -registration updated to point to <tt>value</tt>.</p> -<p>Returns the value of <tt>object</tt> after the call.</p> -</div> <!-- runtime.objc_storeWeak --> - -</div> <!-- runtime --> -</div> <!-- root --> -</body> -</html> diff --git a/docs/AutomaticReferenceCounting.rst b/docs/AutomaticReferenceCounting.rst new file mode 100644 index 00000000000..5c1e7d3dfa1 --- /dev/null +++ b/docs/AutomaticReferenceCounting.rst @@ -0,0 +1,2061 @@ +.. sectnum:: +.. contents:: + :local: + +.. FIXME: move to the stylesheet or Sphinx plugin + +.. raw:: html + + <style> + .arc-term { font-style: italic; font-weight: bold; } + .revision { font-style: italic; } + .when-revised { font-weight: bold; font-style: normal; } + </style> + +.. role:: arc-term +.. role:: revision +.. role:: when-revised + +.. title:: Objective-C Automatic Reference Counting (ARC) + +.. _arc.meta: + +=================== +About this document +=================== + +.. _arc.meta.purpose: + +Purpose +======= + +The first and primary purpose of this document is to serve as a complete +technical specification of Automatic Reference Counting. Given a core +Objective-C compiler and runtime, it should be possible to write a compiler and +runtime which implements these new semantics. + +The secondary purpose is to act as a rationale for why ARC was designed in this +way. This should remain tightly focused on the technical design and should not +stray into marketing speculation. + +.. _arc.meta.background: + +Background +========== + +This document assumes a basic familiarity with C. + +:arc-term:`Blocks` are a C language extension for creating anonymous functions. +Users interact with and transfer block objects using :arc-term:`block +pointers`, which are represented like a normal pointer. A block may capture +values from local variables; when this occurs, memory must be dynamically +allocated. The initial allocation is done on the stack, but the runtime +provides a ``Block_copy`` function which, given a block pointer, either copies +the underlying block object to the heap, setting its reference count to 1 and +returning the new block pointer, or (if the block object is already on the +heap) increases its reference count by 1. The paired function is +``Block_release``, which decreases the reference count by 1 and destroys the +object if the count reaches zero and is on the heap. + +Objective-C is a set of language extensions, significant enough to be +considered a different language. It is a strict superset of C. The extensions +can also be imposed on C++, producing a language called Objective-C++. The +primary feature is a single-inheritance object system; we briefly describe the +modern dialect. + +Objective-C defines a new type kind, collectively called the :arc-term:`object +pointer types`. This kind has two notable builtin members, ``id`` and +``Class``; ``id`` is the final supertype of all object pointers. The validity +of conversions between object pointer types is not checked at runtime. Users +may define :arc-term:`classes`; each class is a type, and the pointer to that +type is an object pointer type. A class may have a superclass; its pointer +type is a subtype of its superclass's pointer type. A class has a set of +:arc-term:`ivars`, fields which appear on all instances of that class. For +every class *T* there's an associated metaclass; it has no fields, its +superclass is the metaclass of *T*'s superclass, and its metaclass is a global +class. Every class has a global object whose class is the class's metaclass; +metaclasses have no associated type, so pointers to this object have type +``Class``. + +A class declaration (``@interface``) declares a set of :arc-term:`methods`. A +method has a return type, a list of argument types, and a :arc-term:`selector`: +a name like ``foo:bar:baz:``, where the number of colons corresponds to the +number of formal arguments. A method may be an instance method, in which case +it can be invoked on objects of the class, or a class method, in which case it +can be invoked on objects of the metaclass. A method may be invoked by +providing an object (called the :arc-term:`receiver`) and a list of formal +arguments interspersed with the selector, like so: + +.. code-block:: objc + + [receiver foo: fooArg bar: barArg baz: bazArg] + +This looks in the dynamic class of the receiver for a method with this name, +then in that class's superclass, etc., until it finds something it can execute. +The receiver "expression" may also be the name of a class, in which case the +actual receiver is the class object for that class, or (within method +definitions) it may be ``super``, in which case the lookup algorithm starts +with the static superclass instead of the dynamic class. The actual methods +dynamically found in a class are not those declared in the ``@interface``, but +those defined in a separate ``@implementation`` declaration; however, when +compiling a call, typechecking is done based on the methods declared in the +``@interface``. + +Method declarations may also be grouped into :arc-term:`protocols`, which are not +inherently associated with any class, but which classes may claim to follow. +Object pointer types may be qualified with additional protocols that the object +is known to support. + +:arc-term:`Class extensions` are collections of ivars and methods, designed to +allow a class's ``@interface`` to be split across multiple files; however, +there is still a primary implementation file which must see the +``@interface``\ s of all class extensions. :arc-term:`Categories` allow +methods (but not ivars) to be declared *post hoc* on an arbitrary class; the +methods in the category's ``@implementation`` will be dynamically added to that +class's method tables which the category is loaded at runtime, replacing those +methods in case of a collision. + +In the standard environment, objects are allocated on the heap, and their +lifetime is manually managed using a reference count. This is done using two +instance methods which all classes are expected to implement: ``retain`` +increases the object's reference count by 1, whereas ``release`` decreases it +by 1 and calls the instance method ``dealloc`` if the count reaches 0. To +simplify certain operations, there is also an :arc-term:`autorelease pool`, a +thread-local list of objects to call ``release`` on later; an object can be +added to this pool by calling ``autorelease`` on it. + +Block pointers may be converted to type ``id``; block objects are laid out in a +way that makes them compatible with Objective-C objects. There is a builtin +class that all block objects are considered to be objects of; this class +implements ``retain`` by adjusting the reference count, not by calling +``Block_copy``. + +.. _arc.meta.evolution: + +Evolution +========= + +ARC is under continual evolution, and this document must be updated as the +language progresses. + +If a change increases the expressiveness of the language, for example by +lifting a restriction or by adding new syntax, the change will be annotated +with a revision marker, like so: + + ARC applies to Objective-C pointer types, block pointer types, and + :when-revised:`[beginning Apple 8.0, LLVM 3.8]` :revision:`BPTRs declared + within` ``extern "BCPL"`` blocks. + +For now, it is sensible to version this document by the releases of its sole +implementation (and its host project), clang. "LLVM X.Y" refers to an +open-source release of clang from the LLVM project. "Apple X.Y" refers to an +Apple-provided release of the Apple LLVM Compiler. Other organizations that +prepare their own, separately-versioned clang releases and wish to maintain +similar information in this document should send requests to cfe-dev. + +If a change decreases the expressiveness of the language, for example by +imposing a new restriction, this should be taken as an oversight in the +original specification and something to be avoided in all versions. Such +changes are generally to be avoided. + +.. _arc.general: + +======= +General +======= + +Automatic Reference Counting implements automatic memory management for +Objective-C objects and blocks, freeing the programmer from the need to +explicitly insert retains and releases. It does not provide a cycle collector; +users must explicitly manage the lifetime of their objects, breaking cycles +manually or with weak or unsafe references. + +ARC may be explicitly enabled with the compiler flag ``-fobjc-arc``. It may +also be explicitly disabled with the compiler flag ``-fno-objc-arc``. The last +of these two flags appearing on the compile line "wins". + +If ARC is enabled, ``__has_feature(objc_arc)`` will expand to 1 in the +preprocessor. For more information about ``__has_feature``, see the +:ref:`language extensions <langext-__has_feature-__has_extension>` document. + +.. _arc.objects: + +========================== +Retainable object pointers +========================== + +This section describes retainable object pointers, their basic operations, and +the restrictions imposed on their use under ARC. Note in particular that it +covers the rules for pointer *values* (patterns of bits indicating the location +of a pointed-to object), not pointer *objects* (locations in memory which store +pointer values). The rules for objects are covered in the next section. + +A :arc-term:`retainable object pointer` (or "retainable pointer") is a value of +a :arc-term:`retainable object pointer type` ("retainable type"). There are +three kinds of retainable object pointer types: + +* block pointers (formed by applying the caret (``^``) declarator sigil to a + function type) +* Objective-C object pointers (``id``, ``Class``, ``NSFoo*``, etc.) +* typedefs marked with ``__attribute__((NSObject))`` + +Other pointer types, such as ``int*`` and ``CFStringRef``, are not subject to +ARC's semantics and restrictions. + +.. admonition:: Rationale + + We are not at liberty to require all code to be recompiled with ARC; + therefore, ARC must interoperate with Objective-C code which manages retains + and releases manually. In general, there are three requirements in order for + a compiler-supported reference-count system to provide reliable + interoperation: + + * The type system must reliably identify which objects are to be managed. An + ``int*`` might be a pointer to a ``malloc``'ed array, or it might be an + interior pointer to such an array, or it might point to some field or local + variable. In contrast, values of the retainable object pointer types are + never interior. + + * The type system must reliably indicate how to manage objects of a type. + This usually means that the type must imply a procedure for incrementing + and decrementing retain counts. Supporting single-ownership objects + requires a lot more explicit mediation in the language. + + * There must be reliable conventions for whether and when "ownership" is + passed between caller and callee, for both arguments and return values. + Objective-C methods follow such a convention very reliably, at least for + system libraries on Mac OS X, and functions always pass objects at +0. The + C-based APIs for Core Foundation objects, on the other hand, have much more + varied transfer semantics. + +The use of ``__attribute__((NSObject))`` typedefs is not recommended. If it's +absolutely necessary to use this attribute, be very explicit about using the +typedef, and do not assume that it will be preserved by language features like +``__typeof`` and C++ template argument substitution. + +.. admonition:: Rationale + + Any compiler operation which incidentally strips type "sugar" from a type + will yield a type without the attribute, which may result in unexpected + behavior. + +.. _arc.objects.retains: + +Retain count semantics +====================== + +A retainable object pointer is either a :arc-term:`null pointer` or a pointer +to a valid object. Furthermore, if it has block pointer type and is not +``null`` then it must actually be a pointer to a block object, and if it has +``Class`` type (possibly protocol-qualified) then it must actually be a pointer +to a class object. Otherwise ARC does not enforce the Objective-C type system +as long as the implementing methods follow the signature of the static type. +It is undefined behavior if ARC is exposed to an invalid pointer. + +For ARC's purposes, a valid object is one with "well-behaved" retaining +operations. Specifically, the object must be laid out such that the +Objective-C message send machinery can successfully send it the following +messages: + +* ``retain``, taking no arguments and returning a pointer to the object. +* ``release``, taking no arguments and returning ``void``. +* ``autorelease``, taking no arguments and returning a pointer to the object. + +The behavior of these methods is constrained in the following ways. The term +:arc-term:`high-level semantics` is an intentionally vague term; the intent is +that programmers must implement these methods in a way such that the compiler, +modifying code in ways it deems safe according to these constraints, will not +violate their requirements. For example, if the user puts logging statements +in ``retain``, they should not be surprised if those statements are executed +more or less often depending on optimization settings. These constraints are +not exhaustive of the optimization opportunities: values held in local +variables are subject to additional restrictions, described later in this +document. + +It is undefined behavior if a computation history featuring a send of +``retain`` followed by a send of ``release`` to the same object, with no +intervening ``release`` on that object, is not equivalent under the high-level +semantics to a computation history in which these sends are removed. Note that +this implies that these methods may not raise exceptions. + +It is undefined behavior if a computation history features any use whatsoever +of an object following the completion of a send of ``release`` that is not +preceded by a send of ``retain`` to the same object. + +The behavior of ``autorelease`` must be equivalent to sending ``release`` when +one of the autorelease pools currently in scope is popped. It may not throw an +exception. + +When the semantics call for performing one of these operations on a retainable +object pointer, if that pointer is ``null`` then the effect is a no-op. + +All of the semantics described in this document are subject to additional +:ref:`optimization rules <arc.optimization>` which permit the removal or +optimization of operations based on local knowledge of data flow. The +semantics describe the high-level behaviors that the compiler implements, not +an exact sequence of operations that a program will be compiled into. + +.. _arc.objects.operands: + +Retainable object pointers as operands and arguments +==================================================== + +In general, ARC does not perform retain or release operations when simply using +a retainable object pointer as an operand within an expression. This includes: + +* loading a retainable pointer from an object with non-weak :ref:`ownership + <arc.ownership>`, +* passing a retainable pointer as an argument to a function or method, and +* receiving a retainable pointer as the result of a function or method call. + +.. admonition:: Rationale + + While this might seem uncontroversial, it is actually unsafe when multiple + expressions are evaluated in "parallel", as with binary operators and calls, + because (for example) one expression might load from an object while another + writes to it. However, C and C++ already call this undefined behavior + because the evaluations are unsequenced, and ARC simply exploits that here to + avoid needing to retain arguments across a large number of calls. + +The remainder of this section describes exceptions to these rules, how those +exceptions are detected, and what those exceptions imply semantically. + +.. _arc.objects.operands.consumed: + +Consumed parameters +------------------- + +A function or method parameter of retainable object pointer type may be marked +as :arc-term:`consumed`, signifying that the callee expects to take ownership +of a +1 retain count. This is done by adding the ``ns_consumed`` attribute to +the parameter declaration, like so: + +.. code-block:: objc + + void foo(__attribute((ns_consumed)) id x); + - (void) foo: (id) __attribute((ns_consumed)) x; + +This attribute is part of the type of the function or method, not the type of +the parameter. It controls only how the argument is passed and received. + +When passing such an argument, ARC retains the argument prior to making the +call. + +When receiving such an argument, ARC releases the argument at the end of the +function, subject to the usual optimizations for local values. + +.. admonition:: Rationale + + This formalizes direct transfers of ownership from a caller to a callee. The + most common scenario here is passing the ``self`` parameter to ``init``, but + it is useful to generalize. Typically, local optimization will remove any + extra retains and releases: on the caller side the retain will be merged with + a +1 source, and on the callee side the release will be rolled into the + initialization of the parameter. + +The implicit ``self`` parameter of a method may be marked as consumed by adding +``__attribute__((ns_consumes_self))`` to the method declaration. Methods in +the ``init`` :ref:`family <arc.method-families>` are treated as if they were +implicitly marked with this attribute. + +It is undefined behavior if an Objective-C message send to a method with +``ns_consumed`` parameters (other than self) is made with a null receiver. It +is undefined behavior if the method to which an Objective-C message send +statically resolves to has a different set of ``ns_consumed`` parameters than +the method it dynamically resolves to. It is undefined behavior if a block or +function call is made through a static type with a different set of +``ns_consumed`` parameters than the implementation of the called block or +function. + +.. admonition:: Rationale + + Consumed parameters with null receiver are a guaranteed leak. Mismatches + with consumed parameters will cause over-retains or over-releases, depending + on the direction. The rule about function calls is really just an + application of the existing C/C++ rule about calling functions through an + incompatible function type, but it's useful to state it explicitly. + +.. _arc.object.operands.retained-return-values: + +Retained return values +---------------------- + +A function or method which returns a retainable object pointer type may be +marked as returning a retained value, signifying that the caller expects to take +ownership of a +1 retain count. This is done by adding the +``ns_returns_retained`` attribute to the function or method declaration, like +so: + +.. code-block:: objc + + id foo(void) __attribute((ns_returns_retained)); + - (id) foo __attribute((ns_returns_retained)); + +This attribute is part of the type of the function or method. + +When returning from such a function or method, ARC retains the value at the +point of evaluation of the return statement, before leaving all local scopes. + +When receiving a return result from such a function or method, ARC releases the +value at the end of the full-expression it is contained within, subject to the +usual optimizations for local values. + +.. admonition:: Rationale + + This formalizes direct transfers of ownership from a callee to a caller. The + most common scenario this models is the retained return from ``init``, + ``alloc``, ``new``, and ``copy`` methods, but there are other cases in the + frameworks. After optimization there are typically no extra retains and + releases required. + +Methods in the ``alloc``, ``copy``, ``init``, ``mutableCopy``, and ``new`` +:ref:`families <arc.method-families>` are implicitly marked +``__attribute__((ns_returns_retained))``. This may be suppressed by explicitly +marking the method ``__attribute__((ns_returns_not_retained))``. + +It is undefined behavior if the method to which an Objective-C message send +statically resolves has different retain semantics on its result from the +method it dynamically resolves to. It is undefined behavior if a block or +function call is made through a static type with different retain semantics on +its result from the implementation of the called block or function. + +.. admonition:: Rationale + + Mismatches with returned results will cause over-retains or over-releases, + depending on the direction. Again, the rule about function calls is really + just an application of the existing C/C++ rule about calling functions + through an incompatible function type. + +.. _arc.objects.operands.unretained-returns: + +Unretained return values +------------------------ + +A method or function which returns a retainable object type but does not return +a retained value must ensure that the object is still valid across the return +boundary. + +When returning from such a function or method, ARC retains the value at the +point of evaluation of the return statement, then leaves all local scopes, and +then balances out the retain while ensuring that the value lives across the +call boundary. In the worst case, this may involve an ``autorelease``, but +callers must not assume that the value is actually in the autorelease pool. + +ARC performs no extra mandatory work on the caller side, although it may elect +to do something to shorten the lifetime of the returned value. + +.. admonition:: Rationale + + It is common in non-ARC code to not return an autoreleased value; therefore + the convention does not force either path. It is convenient to not be + required to do unnecessary retains and autoreleases; this permits + optimizations such as eliding retain/autoreleases when it can be shown that + the original pointer will still be valid at the point of return. + +A method or function may be marked with +``__attribute__((ns_returns_autoreleased))`` to indicate that it returns a +pointer which is guaranteed to be valid at least as long as the innermost +autorelease pool. There are no additional semantics enforced in the definition +of such a method; it merely enables optimizations in callers. + +.. _arc.objects.operands.casts: + +Bridged casts +------------- + +A :arc-term:`bridged cast` is a C-style cast annotated with one of three +keywords: + +* ``(__bridge T) op`` casts the operand to the destination type ``T``. If + ``T`` is a retainable object pointer type, then ``op`` must have a + non-retainable pointer type. If ``T`` is a non-retainable pointer type, + then ``op`` must have a retainable object pointer type. Otherwise the cast + is ill-formed. There is no transfer of ownership, and ARC inserts no retain + operations. +* ``(__bridge_retained T) op`` casts the operand, which must have retainable + object pointer type, to the destination type, which must be a non-retainable + pointer type. ARC retains the value, subject to the usual optimizations on + local values, and the recipient is responsible for balancing that +1. +* ``(__bridge_transfer T) op`` casts the operand, which must have + non-retainable pointer type, to the destination type, which must be a + retainable object pointer type. ARC will release the value at the end of + the enclosing full-expression, subject to the usual optimizations on local + values. + +These casts are required in order to transfer objects in and out of ARC +control; see the rationale in the section on :ref:`conversion of retainable +object pointers <arc.objects.restrictions.conversion>`. + +Using a ``__bridge_retained`` or ``__bridge_transfer`` cast purely to convince +ARC to emit an unbalanced retain or release, respectively, is poor form. + +.. _arc.objects.restrictions: + +Restrictions +============ + +.. _arc.objects.restrictions.conversion: + +Conversion of retainable object pointers +---------------------------------------- + +In general, a program which attempts to implicitly or explicitly convert a +value of retainable object pointer type to any non-retainable type, or +vice-versa, is ill-formed. For example, an Objective-C object pointer shall +not be converted to ``void*``. As an exception, cast to ``intptr_t`` is +allowed because such casts are not transferring ownership. The :ref:`bridged +casts <arc.objects.operands.casts>` may be used to perform these conversions +where necessary. + +.. admonition:: Rationale + + We cannot ensure the correct management of the lifetime of objects if they + may be freely passed around as unmanaged types. The bridged casts are + provided so that the programmer may explicitly describe whether the cast + transfers control into or out of ARC. + +However, the following exceptions apply. + +.. _arc.objects.restrictions.conversion.with.known.semantics: + +Conversion to retainable object pointer type of expressions with known semantics +-------------------------------------------------------------------------------- + +:when-revised:`[beginning Apple 4.0, LLVM 3.1]` +:revision:`These exceptions have been greatly expanded; they previously applied +only to a much-reduced subset which is difficult to categorize but which +included null pointers, message sends (under the given rules), and the various +global constants.` + +An unbridged conversion to a retainable object pointer type from a type other +than a retainable object pointer type is ill-formed, as discussed above, unless +the operand of the cast has a syntactic form which is known retained, known +unretained, or known retain-agnostic. + +An expression is :arc-term:`known retain-agnostic` if it is: + +* an Objective-C string literal, +* a load from a ``const`` system global variable of :ref:`C retainable pointer + type <arc.misc.c-retainable>`, or +* a null pointer constant. + +An expression is :arc-term:`known unretained` if it is an rvalue of :ref:`C +retainable pointer type <arc.misc.c-retainable>` and it is: + +* a direct call to a function, and either that function has the + ``cf_returns_not_retained`` attribute or it is an :ref:`audited + <arc.misc.c-retainable.audit>` function that does not have the + ``cf_returns_retained`` attribute and does not follow the create/copy naming + convention, +* a message send, and the declared method either has the + ``cf_returns_not_retained`` attribute or it has neither the + ``cf_returns_retained`` attribute nor a :ref:`selector family + <arc.method-families>` that implies a retained result. + +An expression is :arc-term:`known retained` if it is an rvalue of :ref:`C +retainable pointer type <arc.misc.c-retainable>` and it is: + +* a message send, and the declared method either has the + ``cf_returns_retained`` attribute, or it does not have the + ``cf_returns_not_retained`` attribute but it does have a :ref:`selector + family <arc.method-families>` that implies a retained result. + +Furthermore: + +* a comma expression is classified according to its right-hand side, +* a statement expression is classified according to its result expression, if + it has one, +* an lvalue-to-rvalue conversion applied to an Objective-C property lvalue is + classified according to the underlying message send, and +* a conditional operator is classified according to its second and third + operands, if they agree in classification, or else the other if one is known + retain-agnostic. + +If the cast operand is known retained, the conversion is treated as a +``__bridge_transfer`` cast. If the cast operand is known unretained or known +retain-agnostic, the conversion is treated as a ``__bridge`` cast. + +.. admonition:: Rationale + + Bridging casts are annoying. Absent the ability to completely automate the + management of CF objects, however, we are left with relatively poor attempts + to reduce the need for a glut of explicit bridges. Hence these rules. + + We've so far consciously refrained from implicitly turning retained CF + results from function calls into ``__bridge_transfer`` casts. The worry is + that some code patterns --- for example, creating a CF value, assigning it + to an ObjC-typed local, and then calling ``CFRelease`` when done --- are a + bit too likely to be accidentally accepted, leading to mysterious behavior. + +.. _arc.objects.restrictions.conversion-exception-contextual: + +Conversion from retainable object pointer type in certain contexts +------------------------------------------------------------------ + +:when-revised:`[beginning Apple 4.0, LLVM 3.1]` + +If an expression of retainable object pointer type is explicitly cast to a +:ref:`C retainable pointer type <arc.misc.c-retainable>`, the program is +ill-formed as discussed above unless the result is immediately used: + +* to initialize a parameter in an Objective-C message send where the parameter + is not marked with the ``cf_consumed`` attribute, or +* to initialize a parameter in a direct call to an + :ref:`audited <arc.misc.c-retainable.audit>` function where the parameter is + not marked with the ``cf_consumed`` attribute. + +.. admonition:: Rationale + + Consumed parameters are left out because ARC would naturally balance them + with a retain, which was judged too treacherous. This is in part because + several of the most common consuming functions are in the ``Release`` family, + and it would be quite unfortunate for explicit releases to be silently + balanced out in this way. + +.. _arc.ownership: + +======================= +Ownership qualification +======================= + +This section describes the behavior of *objects* of retainable object pointer +type; that is, locations in memory which store retainable object pointers. + +A type is a :arc-term:`retainable object owner type` if it is a retainable +object pointer type or an array type whose element type is a retainable object +owner type. + +An :arc-term:`ownership qualifier` is a type qualifier which applies only to +retainable object owner types. An array type is ownership-qualified according +to its element type, and adding an ownership qualifier to an array type so +qualifies its element type. + +A program is ill-formed if it attempts to apply an ownership qualifier to a +type which is already ownership-qualified, even if it is the same qualifier. +There is a single exception to this rule: an ownership qualifier may be applied +to a substituted template type parameter, which overrides the ownership +qualifier provided by the template argument. + +Except as described under the :ref:`inference rules <arc.ownership.inference>`, +a program is ill-formed if it attempts to form a pointer or reference type to a +retainable object owner type which lacks an ownership qualifier. + +.. admonition:: Rationale + + These rules, together with the inference rules, ensure that all objects and + lvalues of retainable object pointer type have an ownership qualifier. The + ability to override an ownership qualifier during template substitution is + required to counteract the :ref:`inference of __strong for template type + arguments <arc.ownership.inference.template.arguments>`. + +There are four ownership qualifiers: + +* ``__autoreleasing`` +* ``__strong`` +* ``__unsafe_unretained`` +* ``__weak`` + +A type is :arc-term:`nontrivially ownership-qualified` if it is qualified with +``__autoreleasing``, ``__strong``, or ``__weak``. + +.. _arc.ownership.spelling: + +Spelling +======== + +The names of the ownership qualifiers are reserved for the implementation. A +program may not assume that they are or are not implemented with macros, or +what those macros expand to. + +An ownership qualifier may be written anywhere that any other type qualifier +may be written. + +If an ownership qualifier appears in the *declaration-specifiers*, the +following rules apply: + +* if the type specifier is a retainable object owner type, the qualifier + applies to that type; +* if the outermost non-array part of the declarator is a pointer or block + pointer, the qualifier applies to that type; +* otherwise the program is ill-formed. + +If an ownership qualifier appears on the declarator name, or on the declared +object, it is applied to outermost pointer or block-pointer type. + +If an ownership qualifier appears anywhere else in a declarator, it applies to +the type there. + +.. _arc.ownership.spelling.property: + +Property declarations +--------------------- + +A property of retainable object pointer type may have ownership. If the +property's type is ownership-qualified, then the property has that ownership. +If the property has one of the following modifiers, then the property has the +corresponding ownership. A property is ill-formed if it has conflicting +sources of ownership, or if it has redundant ownership modifiers, or if it has +``__autoreleasing`` ownership. + +* ``assign`` implies ``__unsafe_unretained`` ownership. +* ``copy`` implies ``__strong`` ownership, as well as the usual behavior of + copy semantics on the setter. +* ``retain`` implies ``__strong`` ownership. +* ``strong`` implies ``__strong`` ownership. +* ``unsafe_unretained`` implies ``__unsafe_unretained`` ownership. +* ``weak`` implies ``__weak`` ownership. + +With the exception of ``weak``, these modifiers are available in non-ARC +modes. + +A property's specified ownership is preserved in its metadata, but otherwise +the meaning is purely conventional unless the property is synthesized. If a +property is synthesized, then the :arc-term:`associated instance variable` is +the instance variable which is named, possibly implicitly, by the +``@synthesize`` declaration. If the associated instance variable already +exists, then its ownership qualification must equal the ownership of the +property; otherwise, the instance variable is created with that ownership +qualification. + +A property of retainable object pointer type which is synthesized without a +source of ownership has the ownership of its associated instance variable, if it +already exists; otherwise, :when-revised:`[beginning Apple 3.1, LLVM 3.1]` +:revision:`its ownership is implicitly` ``strong``. Prior to this revision, it +was ill-formed to synthesize such a property. + +.. admonition:: Rationale + + Using ``strong`` by default is safe and consistent with the generic ARC rule + about :ref:`inferring ownership <arc.ownership.inference.variables>`. It is, + unfortunately, inconsistent with the non-ARC rule which states that such + properties are implicitly ``assign``. However, that rule is clearly + untenable in ARC, since it leads to default-unsafe code. The main merit to + banning the properties is to avoid confusion with non-ARC practice, which did + not ultimately strike us as sufficient to justify requiring extra syntax and + (more importantly) forcing novices to understand ownership rules just to + declare a property when the default is so reasonable. Changing the rule away + from non-ARC practice was acceptable because we had conservatively banned the + synthesis in order to give ourselves exactly this leeway. + +Applying ``__attribute__((NSObject))`` to a property not of retainable object +pointer type has the same behavior it does outside of ARC: it requires the +property type to be some sort of pointer and permits the use of modifiers other +than ``assign``. These modifiers only affect the synthesized getter and +setter; direct accesses to the ivar (even if synthesized) still have primitive +semantics, and the value in the ivar will not be automatically released during +deallocation. + +.. _arc.ownership.semantics: + +Semantics +========= + +There are five :arc-term:`managed operations` which may be performed on an +object of retainable object pointer type. Each qualifier specifies different +semantics for each of these operations. It is still undefined behavior to +access an object outside of its lifetime. + +A load or store with "primitive semantics" has the same semantics as the +respective operation would have on an ``void*`` lvalue with the same alignment +and non-ownership qualification. + +:arc-term:`Reading` occurs when performing a lvalue-to-rvalue conversion on an +object lvalue. + +* For ``__weak`` objects, the current pointee is retained and then released at + the end of the current full-expression. This must execute atomically with + respect to assignments and to the final release of the pointee. +* For all other objects, the lvalue is loaded with primitive semantics. + +:arc-term:`Assignment` occurs when evaluating an assignment operator. The +semantics vary based on the qualification: + +* For ``__strong`` objects, the new pointee is first retained; second, the + lvalue is loaded with primitive semantics; third, the new pointee is stored + into the lvalue with primitive semantics; and finally, the old pointee is + released. This is not performed atomically; external synchronization must be + used to make this safe in the face of concurrent loads and stores. +* For ``__weak`` objects, the lvalue is updated to point to the new pointee, + unless the new pointee is an object currently undergoing deallocation, in + which case the lvalue is updated to a null pointer. This must execute + atomically with respect to other assignments to the object, to reads from the + object, and to the final release of the new pointee. +* For ``__unsafe_unretained`` objects, the new pointee is stored into the + lvalue using primitive semantics. +* For ``__autoreleasing`` objects, the new pointee is retained, autoreleased, + and stored into the lvalue using primitive semantics. + +:arc-term:`Initialization` occurs when an object's lifetime begins, which +depends on its storage duration. Initialization proceeds in two stages: + +#. First, a null pointer is stored into the lvalue using primitive semantics. + This step is skipped if the object is ``__unsafe_unretained``. +#. Second, if the object has an initializer, that expression is evaluated and + then assigned into the object using the usual assignment semantics. + +:arc-term:`Destruction` occurs when an object's lifetime ends. In all cases it +is semantically equivalent to assigning a null pointer to the object, with the +proviso that of course the object cannot be legally read after the object's +lifetime ends. + +:arc-term:`Moving` occurs in specific situations where an lvalue is "moved +from", meaning that its current pointee will be used but the object may be left +in a different (but still valid) state. This arises with ``__block`` variables +and rvalue references in C++. For ``__strong`` lvalues, moving is equivalent +to loading the lvalue with primitive semantics, writing a null pointer to it +with primitive semantics, and then releasing the result of the load at the end +of the current full-expression. For all other lvalues, moving is equivalent to +reading the object. + +.. _arc.ownership.restrictions: + +Restrictions +============ + +.. _arc.ownership.restrictions.weak: + +Weak-unavailable types +---------------------- + +It is explicitly permitted for Objective-C classes to not support ``__weak`` +references. It is undefined behavior to perform an operation with weak +assignment semantics with a pointer to an Objective-C object whose class does +not support ``__weak`` references. + +.. admonition:: Rationale + + Historically, it has been possible for a class to provide its own + reference-count implementation by overriding ``retain``, ``release``, etc. + However, weak references to an object require coordination with its class's + reference-count implementation because, among other things, weak loads and + stores must be atomic with respect to the final release. Therefore, existing + custom reference-count implementations will generally not support weak + references without additional effort. This is unavoidable without breaking + binary compatibility. + +A class may indicate that it does not support weak references by providing the +``objc_arc_weak_unavailable`` attribute on the class's interface declaration. A +retainable object pointer type is **weak-unavailable** if +is a pointer to an (optionally protocol-qualified) Objective-C class ``T`` where +``T`` or one of its superclasses has the ``objc_arc_weak_unavailable`` +attribute. A program is ill-formed if it applies the ``__weak`` ownership +qualifier to a weak-unavailable type or if the value operand of a weak +assignment operation has a weak-unavailable type. + +.. _arc.ownership.restrictions.autoreleasing: + +Storage duration of ``__autoreleasing`` objects +----------------------------------------------- + +A program is ill-formed if it declares an ``__autoreleasing`` object of +non-automatic storage duration. A program is ill-formed if it captures an +``__autoreleasing`` object in a block or, unless by reference, in a C++11 +lambda. + +.. admonition:: Rationale + + Autorelease pools are tied to the current thread and scope by their nature. + While it is possible to have temporary objects whose instance variables are + filled with autoreleased objects, there is no way that ARC can provide any + sort of safety guarantee there. + +It is undefined behavior if a non-null pointer is assigned to an +``__autoreleasing`` object while an autorelease pool is in scope and then that +object is read after the autorelease pool's scope is left. + +.. _arc.ownership.restrictions.conversion.indirect: + +Conversion of pointers to ownership-qualified types +--------------------------------------------------- + +A program is ill-formed if an expression of type ``T*`` is converted, +explicitly or implicitly, to the type ``U*``, where ``T`` and ``U`` have +different ownership qualification, unless: + +* ``T`` is qualified with ``__strong``, ``__autoreleasing``, or + ``__unsafe_unretained``, and ``U`` is qualified with both ``const`` and + ``__unsafe_unretained``; or +* either ``T`` or ``U`` is ``cv void``, where ``cv`` is an optional sequence + of non-ownership qualifiers; or +* the conversion is requested with a ``reinterpret_cast`` in Objective-C++; or +* the conversion is a well-formed :ref:`pass-by-writeback + <arc.ownership.restrictions.pass_by_writeback>`. + +The analogous rule applies to ``T&`` and ``U&`` in Objective-C++. + +.. admonition:: Rationale + + These rules provide a reasonable level of type-safety for indirect pointers, + as long as the underlying memory is not deallocated. The conversion to + ``const __unsafe_unretained`` is permitted because the semantics of reads are + equivalent across all these ownership semantics, and that's a very useful and + common pattern. The interconversion with ``void*`` is useful for allocating + memory or otherwise escaping the type system, but use it carefully. + ``reinterpret_cast`` is considered to be an obvious enough sign of taking + responsibility for any problems. + +It is undefined behavior to access an ownership-qualified object through an +lvalue of a differently-qualified type, except that any non-``__weak`` object +may be read through an ``__unsafe_unretained`` lvalue. + +It is undefined behavior if a managed operation is performed on a ``__strong`` +or ``__weak`` object without a guarantee that it contains a primitive zero +bit-pattern, or if the storage for such an object is freed or reused without the +object being first assigned a null pointer. + +.. admonition:: Rationale + + ARC cannot differentiate between an assignment operator which is intended to + "initialize" dynamic memory and one which is intended to potentially replace + a value. Therefore the object's pointer must be valid before letting ARC at + it. Similarly, C and Objective-C do not provide any language hooks for + destroying objects held in dynamic memory, so it is the programmer's + responsibility to avoid leaks (``__strong`` objects) and consistency errors + (``__weak`` objects). + +These requirements are followed automatically in Objective-C++ when creating +objects of retainable object owner type with ``new`` or ``new[]`` and destroying +them with ``delete``, ``delete[]``, or a pseudo-destructor expression. Note +that arrays of nontrivially-ownership-qualified type are not ABI compatible with +non-ARC code because the element type is non-POD: such arrays that are +``new[]``'d in ARC translation units cannot be ``delete[]``'d in non-ARC +translation units and vice-versa. + +.. _arc.ownership.restrictions.pass_by_writeback: + +Passing to an out parameter by writeback +---------------------------------------- + +If the argument passed to a parameter of type ``T __autoreleasing *`` has type +``U oq *``, where ``oq`` is an ownership qualifier, then the argument is a +candidate for :arc-term:`pass-by-writeback`` if: + +* ``oq`` is ``__strong`` or ``__weak``, and +* it would be legal to initialize a ``T __strong *`` with a ``U __strong *``. + +For purposes of overload resolution, an implicit conversion sequence requiring +a pass-by-writeback is always worse than an implicit conversion sequence not +requiring a pass-by-writeback. + +The pass-by-writeback is ill-formed if the argument expression does not have a +legal form: + +* ``&var``, where ``var`` is a scalar variable of automatic storage duration + with retainable object pointer type +* a conditional expression where the second and third operands are both legal + forms +* a cast whose operand is a legal form +* a null pointer constant + +.. admonition:: Rationale + + The restriction in the form of the argument serves two purposes. First, it + makes it impossible to pass the address of an array to the argument, which + serves to protect against an otherwise serious risk of mis-inferring an + "array" argument as an out-parameter. Second, it makes it much less likely + that the user will see confusing aliasing problems due to the implementation, + below, where their store to the writeback temporary is not immediately seen + in the original argument variable. + +A pass-by-writeback is evaluated as follows: + +#. The argument is evaluated to yield a pointer ``p`` of type ``U oq *``. +#. If ``p`` is a null pointer, then a null pointer is passed as the argument, + and no further work is required for the pass-by-writeback. +#. Otherwise, a temporary of type ``T __autoreleasing`` is created and + initialized to a null pointer. +#. If the parameter is not an Objective-C method parameter marked ``out``, + then ``*p`` is read, and the result is written into the temporary with + primitive semantics. +#. The address of the temporary is passed as the argument to the actual call. +#. After the call completes, the temporary is loaded with primitive + semantics, and that value is assigned into ``*p``. + +.. admonition:: Rationale + + This is all admittedly convoluted. In an ideal world, we would see that a + local variable is being passed to an out-parameter and retroactively modify + its type to be ``__autoreleasing`` rather than ``__strong``. This would be + remarkably difficult and not always well-founded under the C type system. + However, it was judged unacceptably invasive to require programmers to write + ``__autoreleasing`` on all the variables they intend to use for + out-parameters. This was the least bad solution. + +.. _arc.ownership.restrictions.records: + +Ownership-qualified fields of structs and unions +------------------------------------------------ + +A program is ill-formed if it declares a member of a C struct or union to have +a nontrivially ownership-qualified type. + +.. admonition:: Rationale + + The resulting type would be non-POD in the C++ sense, but C does not give us + very good language tools for managing the lifetime of aggregates, so it is + more convenient to simply forbid them. It is still possible to manage this + with a ``void*`` or an ``__unsafe_unretained`` object. + +This restriction does not apply in Objective-C++. However, nontrivally +ownership-qualified types are considered non-POD: in C++11 terms, they are not +trivially default constructible, copy constructible, move constructible, copy +assignable, move assignable, or destructible. It is a violation of C++'s One +Definition Rule to use a class outside of ARC that, under ARC, would have a +nontrivially ownership-qualified member. + +.. admonition:: Rationale + + Unlike in C, we can express all the necessary ARC semantics for + ownership-qualified subobjects as suboperations of the (default) special + member functions for the class. These functions then become non-trivial. + This has the non-obvious result that the class will have a non-trivial copy + constructor and non-trivial destructor; if this would not normally be true + outside of ARC, objects of the type will be passed and returned in an + ABI-incompatible manner. + +.. _arc.ownership.inference: + +Ownership inference +=================== + +.. _arc.ownership.inference.variables: + +Objects +------- + +If an object is declared with retainable object owner type, but without an +explicit ownership qualifier, its type is implicitly adjusted to have +``__strong`` qualification. + +As a special case, if the object's base type is ``Class`` (possibly +protocol-qualified), the type is adjusted to have ``__unsafe_unretained`` +qualification instead. + +.. _arc.ownership.inference.indirect_parameters: + +Indirect parameters +------------------- + +If a function or method parameter has type ``T*``, where ``T`` is an +ownership-unqualified retainable object pointer type, then: + +* if ``T`` is ``const``-qualified or ``Class``, then it is implicitly + qualified with ``__unsafe_unretained``; +* otherwise, it is implicitly qualified with ``__autoreleasing``. + +.. admonition:: Rationale + + ``__autoreleasing`` exists mostly for this case, the Cocoa convention for + out-parameters. Since a pointer to ``const`` is obviously not an + out-parameter, we instead use a type more useful for passing arrays. If the + user instead intends to pass in a *mutable* array, inferring + ``__autoreleasing`` is the wrong thing to do; this directs some of the + caution in the following rules about writeback. + +Such a type written anywhere else would be ill-formed by the general rule +requiring ownership qualifiers. + +This rule does not apply in Objective-C++ if a parameter's type is dependent in +a template pattern and is only *instantiated* to a type which would be a +pointer to an unqualified retainable object pointer type. Such code is still +ill-formed. + +.. admonition:: Rationale + + The convention is very unlikely to be intentional in template code. + +.. _arc.ownership.inference.template.arguments: + +Template arguments +------------------ + +If a template argument for a template type parameter is an retainable object +owner type that does not have an explicit ownership qualifier, it is adjusted +to have ``__strong`` qualification. This adjustment occurs regardless of +whether the template argument was deduced or explicitly specified. + +.. admonition:: Rationale + + ``__strong`` is a useful default for containers (e.g., ``std::vector<id>``), + which would otherwise require explicit qualification. Moreover, unqualified + retainable object pointer types are unlikely to be useful within templates, + since they generally need to have a qualifier applied to the before being + used. + +.. _arc.method-families: + +=============== +Method families +=============== + +An Objective-C method may fall into a :arc-term:`method family`, which is a +conventional set of behaviors ascribed to it by the Cocoa conventions. + +A method is in a certain method family if: + +* it has a ``objc_method_family`` attribute placing it in that family; or if + not that, +* it does not have an ``objc_method_family`` attribute placing it in a + different or no family, and +* its selector falls into the corresponding selector family, and +* its signature obeys the added restrictions of the method family. + +A selector is in a certain selector family if, ignoring any leading +underscores, the first component of the selector either consists entirely of +the name of the method family or it begins with that name followed by a +character other than a lowercase letter. For example, ``_perform:with:`` and +``performWith:`` would fall into the ``perform`` family (if we recognized one), +but ``performing:with`` would not. + +The families and their added restrictions are: + +* ``alloc`` methods must return a retainable object pointer type. +* ``copy`` methods must return a retainable object pointer type. +* ``mutableCopy`` methods must return a retainable object pointer type. +* ``new`` methods must return a retainable object pointer type. +* ``init`` methods must be instance methods and must return an Objective-C + pointer type. Additionally, a program is ill-formed if it declares or + contains a call to an ``init`` method whose return type is neither ``id`` nor + a pointer to a super-class or sub-class of the declaring class (if the method + was declared on a class) or the static receiver type of the call (if it was + declared on a protocol). + + .. admonition:: Rationale + + There are a fair number of existing methods with ``init``-like selectors + which nonetheless don't follow the ``init`` conventions. Typically these + are either accidental naming collisions or helper methods called during + initialization. Because of the peculiar retain/release behavior of + ``init`` methods, it's very important not to treat these methods as + ``init`` methods if they aren't meant to be. It was felt that implicitly + defining these methods out of the family based on the exact relationship + between the return type and the declaring class would be much too subtle + and fragile. Therefore we identify a small number of legitimate-seeming + return types and call everything else an error. This serves the secondary + purpose of encouraging programmers not to accidentally give methods names + in the ``init`` family. + + Note that a method with an ``init``-family selector which returns a + non-Objective-C type (e.g. ``void``) is perfectly well-formed; it simply + isn't in the ``init`` family. + +A program is ill-formed if a method's declarations, implementations, and +overrides do not all have the same method family. + +.. _arc.family.attribute: + +Explicit method family control +============================== + +A method may be annotated with the ``objc_method_family`` attribute to +precisely control which method family it belongs to. If a method in an +``@implementation`` does not have this attribute, but there is a method +declared in the corresponding ``@interface`` that does, then the attribute is +copied to the declaration in the ``@implementation``. The attribute is +available outside of ARC, and may be tested for with the preprocessor query +``__has_attribute(objc_method_family)``. + +The attribute is spelled +``__attribute__((objc_method_family(`` *family* ``)))``. If *family* is +``none``, the method has no family, even if it would otherwise be considered to +have one based on its selector and type. Otherwise, *family* must be one of +``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``, in which case the +method is considered to belong to the corresponding family regardless of its +selector. It is an error if a method that is explicitly added to a family in +this way does not meet the requirements of the family other than the selector +naming convention. + +.. admonition:: Rationale + + The rules codified in this document describe the standard conventions of + Objective-C. However, as these conventions have not heretofore been enforced + by an unforgiving mechanical system, they are only imperfectly kept, + especially as they haven't always even been precisely defined. While it is + possible to define low-level ownership semantics with attributes like + ``ns_returns_retained``, this attribute allows the user to communicate + semantic intent, which is of use both to ARC (which, e.g., treats calls to + ``init`` specially) and the static analyzer. + +.. _arc.family.semantics: + +Semantics of method families +============================ + +A method's membership in a method family may imply non-standard semantics for +its parameters and return type. + +Methods in the ``alloc``, ``copy``, ``mutableCopy``, and ``new`` families --- +that is, methods in all the currently-defined families except ``init`` --- +implicitly :ref:`return a retained object +<arc.object.operands.retained-return-values>` as if they were annotated with +the ``ns_returns_retained`` attribute. This can be overridden by annotating +the method with either of the ``ns_returns_autoreleased`` or +``ns_returns_not_retained`` attributes. + +Properties also follow same naming rules as methods. This means that those in +the ``alloc``, ``copy``, ``mutableCopy``, and ``new`` families provide access +to :ref:`retained objects <arc.object.operands.retained-return-values>`. This +can be overridden by annotating the property with ``ns_returns_not_retained`` +attribute. + +.. _arc.family.semantics.init: + +Semantics of ``init`` +--------------------- + +Methods in the ``init`` family implicitly :ref:`consume +<arc.objects.operands.consumed>` their ``self`` parameter and :ref:`return a +retained object <arc.object.operands.retained-return-values>`. Neither of +these properties can be altered through attributes. + +A call to an ``init`` method with a receiver that is either ``self`` (possibly +parenthesized or casted) or ``super`` is called a :arc-term:`delegate init +call`. It is an error for a delegate init call to be made except from an +``init`` method, and excluding blocks within such methods. + +As an exception to the :ref:`usual rule <arc.misc.self>`, the variable ``self`` +is mutable in an ``init`` method and has the usual semantics for a ``__strong`` +variable. However, it is undefined behavior and the program is ill-formed, no +diagnostic required, if an ``init`` method attempts to use the previous value +of ``self`` after the completion of a delegate init call. It is conventional, +but not required, for an ``init`` method to return ``self``. + +It is undefined behavior for a program to cause two or more calls to ``init`` +methods on the same object, except that each ``init`` method invocation may +perform at most one delegate init call. + +.. _arc.family.semantics.result_type: + +Related result types +-------------------- + +Certain methods are candidates to have :arc-term:`related result types`: + +* class methods in the ``alloc`` and ``new`` method families +* instance methods in the ``init`` family +* the instance method ``self`` +* outside of ARC, the instance methods ``retain`` and ``autorelease`` + +If the formal result type of such a method is ``id`` or protocol-qualified +``id``, or a type equal to the declaring class or a superclass, then it is said +to have a related result type. In this case, when invoked in an explicit +message send, it is assumed to return a type related to the type of the +receiver: + +* if it is a class method, and the receiver is a class name ``T``, the message + send expression has type ``T*``; otherwise +* if it is an instance method, and the receiver has type ``T``, the message + send expression has type ``T``; otherwise +* the message send expression has the normal result type of the method. + +This is a new rule of the Objective-C language and applies outside of ARC. + +.. admonition:: Rationale + + ARC's automatic code emission is more prone than most code to signature + errors, i.e. errors where a call was emitted against one method signature, + but the implementing method has an incompatible signature. Having more + precise type information helps drastically lower this risk, as well as + catching a number of latent bugs. + +.. _arc.optimization: + +============ +Optimization +============ + +ARC applies aggressive rules for the optimization of local behavior. These +rules are based around a core assumption of :arc-term:`local balancing`: that +other code will perform retains and releases as necessary (and only as +necessary) for its own safety, and so the optimizer does not need to consider +global properties of the retain and release sequence. For example, if a retain +and release immediately bracket a call, the optimizer can delete the retain and +release on the assumption that the called function will not do a constant +number of unmotivated releases followed by a constant number of "balancing" +retains, such that the local retain/release pair is the only thing preventing +the called function from ending up with a dangling reference. + +The optimizer assumes that when a new value enters local control, e.g. from a +load of a non-local object or as the result of a function call, it is +instaneously valid. Subsequently, a retain and release of a value are +necessary on a computation path only if there is a use of that value before the +release and after any operation which might cause a release of the value +(including indirectly or non-locally), and only if the value is not +demonstrably already retained. + +The complete optimization rules are quite complicated, but it would still be +useful to document them here. + +.. _arc.optimization.precise: + +Precise lifetime semantics +========================== + +In general, ARC maintains an invariant that a retainable object pointer held in +a ``__strong`` object will be retained for the full formal lifetime of the +object. Objects subject to this invariant have :arc-term:`precise lifetime +semantics`. + +By default, local variables of automatic storage duration do not have precise +lifetime semantics. Such objects are simply strong references which hold +values of retainable object pointer type, and these values are still fully +subject to the optimizations on values under local control. + +.. admonition:: Rationale + + Applying these precise-lifetime semantics strictly would be prohibitive. + Many useful optimizations that might theoretically decrease the lifetime of + an object would be rendered impossible. Essentially, it promises too much. + +A local variable of retainable object owner type and automatic storage duration +may be annotated with the ``objc_precise_lifetime`` attribute to indicate that +it should be considered to be an object with precise lifetime semantics. + +.. admonition:: Rationale + + Nonetheless, it is sometimes useful to be able to force an object to be + released at a precise time, even if that object does not appear to be used. + This is likely to be uncommon enough that the syntactic weight of explicitly + requesting these semantics will not be burdensome, and may even make the code + clearer. + +.. _arc.misc: + +============= +Miscellaneous +============= + +.. _arc.misc.special_methods: + +Special methods +=============== + +.. _arc.misc.special_methods.retain: + +Memory management methods +------------------------- + +A program is ill-formed if it contains a method definition, message send, or +``@selector`` expression for any of the following selectors: + +* ``autorelease`` +* ``release`` +* ``retain`` +* ``retainCount`` + +.. admonition:: Rationale + + ``retainCount`` is banned because ARC robs it of consistent semantics. The + others were banned after weighing three options for how to deal with message + sends: + + **Honoring** them would work out very poorly if a programmer naively or + accidentally tried to incorporate code written for manual retain/release code + into an ARC program. At best, such code would do twice as much work as + necessary; quite frequently, however, ARC and the explicit code would both + try to balance the same retain, leading to crashes. The cost is losing the + ability to perform "unrooted" retains, i.e. retains not logically + corresponding to a strong reference in the object graph. + + **Ignoring** them would badly violate user expectations about their code. + While it *would* make it easier to develop code simultaneously for ARC and + non-ARC, there is very little reason to do so except for certain library + developers. ARC and non-ARC translation units share an execution model and + can seamlessly interoperate. Within a translation unit, a developer who + faithfully maintains their code in non-ARC mode is suffering all the + restrictions of ARC for zero benefit, while a developer who isn't testing the + non-ARC mode is likely to be unpleasantly surprised if they try to go back to + it. + + **Banning** them has the disadvantage of making it very awkward to migrate + existing code to ARC. The best answer to that, given a number of other + changes and restrictions in ARC, is to provide a specialized tool to assist + users in that migration. + + Implementing these methods was banned because they are too integral to the + semantics of ARC; many tricks which worked tolerably under manual reference + counting will misbehave if ARC performs an ephemeral extra retain or two. If + absolutely required, it is still possible to implement them in non-ARC code, + for example in a category; the implementations must obey the :ref:`semantics + <arc.objects.retains>` laid out elsewhere in this document. + +.. _arc.misc.special_methods.dealloc: + +``dealloc`` +----------- + +A program is ill-formed if it contains a message send or ``@selector`` +expression for the selector ``dealloc``. + +.. admonition:: Rationale + + There are no legitimate reasons to call ``dealloc`` directly. + +A class may provide a method definition for an instance method named +``dealloc``. This method will be called after the final ``release`` of the +object but before it is deallocated or any of its instance variables are +destroyed. The superclass's implementation of ``dealloc`` will be called +automatically when the method returns. + +.. admonition:: Rationale + + Even though ARC destroys instance variables automatically, there are still + legitimate reasons to write a ``dealloc`` method, such as freeing + non-retainable resources. Failing to call ``[super dealloc]`` in such a + method is nearly always a bug. Sometimes, the object is simply trying to + prevent itself from being destroyed, but ``dealloc`` is really far too late + for the object to be raising such objections. Somewhat more legitimately, an + object may have been pool-allocated and should not be deallocated with + ``free``; for now, this can only be supported with a ``dealloc`` + implementation outside of ARC. Such an implementation must be very careful + to do all the other work that ``NSObject``'s ``dealloc`` would, which is + outside the scope of this document to describe. + +The instance variables for an ARC-compiled class will be destroyed at some +point after control enters the ``dealloc`` method for the root class of the +class. The ordering of the destruction of instance variables is unspecified, +both within a single class and between subclasses and superclasses. + +.. admonition:: Rationale + + The traditional, non-ARC pattern for destroying instance variables is to + destroy them immediately before calling ``[super dealloc]``. Unfortunately, + message sends from the superclass are quite capable of reaching methods in + the subclass, and those methods may well read or write to those instance + variables. Making such message sends from dealloc is generally discouraged, + since the subclass may well rely on other invariants that were broken during + ``dealloc``, but it's not so inescapably dangerous that we felt comfortable + calling it undefined behavior. Therefore we chose to delay destroying the + instance variables to a point at which message sends are clearly disallowed: + the point at which the root class's deallocation routines take over. + + In most code, the difference is not observable. It can, however, be observed + if an instance variable holds a strong reference to an object whose + deallocation will trigger a side-effect which must be carefully ordered with + respect to the destruction of the super class. Such code violates the design + principle that semantically important behavior should be explicit. A simple + fix is to clear the instance variable manually during ``dealloc``; a more + holistic solution is to move semantically important side-effects out of + ``dealloc`` and into a separate teardown phase which can rely on working with + well-formed objects. + +.. _arc.misc.autoreleasepool: + +``@autoreleasepool`` +==================== + +To simplify the use of autorelease pools, and to bring them under the control +of the compiler, a new kind of statement is available in Objective-C. It is +written ``@autoreleasepool`` followed by a *compound-statement*, i.e. by a new +scope delimited by curly braces. Upon entry to this block, the current state +of the autorelease pool is captured. When the block is exited normally, +whether by fallthrough or directed control flow (such as ``return`` or +``break``), the autorelease pool is restored to the saved state, releasing all +the objects in it. When the block is exited with an exception, the pool is not +drained. + +``@autoreleasepool`` may be used in non-ARC translation units, with equivalent +semantics. + +A program is ill-formed if it refers to the ``NSAutoreleasePool`` class. + +.. admonition:: Rationale + + Autorelease pools are clearly important for the compiler to reason about, but + it is far too much to expect the compiler to accurately reason about control + dependencies between two calls. It is also very easy to accidentally forget + to drain an autorelease pool when using the manual API, and this can + significantly inflate the process's high-water-mark. The introduction of a + new scope is unfortunate but basically required for sane interaction with the + rest of the language. Not draining the pool during an unwind is apparently + required by the Objective-C exceptions implementation. + +.. _arc.misc.self: + +``self`` +======== + +The ``self`` parameter variable of an Objective-C method is never actually +retained by the implementation. It is undefined behavior, or at least +dangerous, to cause an object to be deallocated during a message send to that +object. + +To make this safe, for Objective-C instance methods ``self`` is implicitly +``const`` unless the method is in the :ref:`init family +<arc.family.semantics.init>`. Further, ``self`` is **always** implicitly +``const`` within a class method. + +.. admonition:: Rationale + + The cost of retaining ``self`` in all methods was found to be prohibitive, as + it tends to be live across calls, preventing the optimizer from proving that + the retain and release are unnecessary --- for good reason, as it's quite + possible in theory to cause an object to be deallocated during its execution + without this retain and release. Since it's extremely uncommon to actually + do so, even unintentionally, and since there's no natural way for the + programmer to remove this retain/release pair otherwise (as there is for + other parameters by, say, making the variable ``__unsafe_unretained``), we + chose to make this optimizing assumption and shift some amount of risk to the + user. + +.. _arc.misc.enumeration: + +Fast enumeration iteration variables +==================================== + +If a variable is declared in the condition of an Objective-C fast enumeration +loop, and the variable has no explicit ownership qualifier, then it is +qualified with ``const __strong`` and objects encountered during the +enumeration are not actually retained. + +.. admonition:: Rationale + + This is an optimization made possible because fast enumeration loops promise + to keep the objects retained during enumeration, and the collection itself + cannot be synchronously modified. It can be overridden by explicitly + qualifying the variable with ``__strong``, which will make the variable + mutable again and cause the loop to retain the objects it encounters. + +.. _arc.misc.blocks: + +Blocks +====== + +The implicit ``const`` capture variables created when evaluating a block +literal expression have the same ownership semantics as the local variables +they capture. The capture is performed by reading from the captured variable +and initializing the capture variable with that value; the capture variable is +destroyed when the block literal is, i.e. at the end of the enclosing scope. + +The :ref:`inference <arc.ownership.inference>` rules apply equally to +``__block`` variables, which is a shift in semantics from non-ARC, where +``__block`` variables did not implicitly retain during capture. + +``__block`` variables of retainable object owner type are moved off the stack +by initializing the heap copy with the result of moving from the stack copy. + +With the exception of retains done as part of initializing a ``__strong`` +parameter variable or reading a ``__weak`` variable, whenever these semantics +call for retaining a value of block-pointer type, it has the effect of a +``Block_copy``. The optimizer may remove such copies when it sees that the +result is used only as an argument to a call. + +.. _arc.misc.exceptions: + +Exceptions +========== + +By default in Objective C, ARC is not exception-safe for normal releases: + +* It does not end the lifetime of ``__strong`` variables when their scopes are + abnormally terminated by an exception. +* It does not perform releases which would occur at the end of a + full-expression if that full-expression throws an exception. + +A program may be compiled with the option ``-fobjc-arc-exceptions`` in order to +enable these, or with the option ``-fno-objc-arc-exceptions`` to explicitly +disable them, with the last such argument "winning". + +.. admonition:: Rationale + + The standard Cocoa convention is that exceptions signal programmer error and + are not intended to be recovered from. Making code exceptions-safe by + default would impose severe runtime and code size penalties on code that + typically does not actually care about exceptions safety. Therefore, + ARC-generated code leaks by default on exceptions, which is just fine if the + process is going to be immediately terminated anyway. Programs which do care + about recovering from exceptions should enable the option. + +In Objective-C++, ``-fobjc-arc-exceptions`` is enabled by default. + +.. admonition:: Rationale + + C++ already introduces pervasive exceptions-cleanup code of the sort that ARC + introduces. C++ programmers who have not already disabled exceptions are + much more likely to actual require exception-safety. + +ARC does end the lifetimes of ``__weak`` objects when an exception terminates +their scope unless exceptions are disabled in the compiler. + +.. admonition:: Rationale + + The consequence of a local ``__weak`` object not being destroyed is very + likely to be corruption of the Objective-C runtime, so we want to be safer + here. Of course, potentially massive leaks are about as likely to take down + the process as this corruption is if the program does try to recover from + exceptions. + +.. _arc.misc.interior: + +Interior pointers +================= + +An Objective-C method returning a non-retainable pointer may be annotated with +the ``objc_returns_inner_pointer`` attribute to indicate that it returns a +handle to the internal data of an object, and that this reference will be +invalidated if the object is destroyed. When such a message is sent to an +object, the object's lifetime will be extended until at least the earliest of: + +* the last use of the returned pointer, or any pointer derived from it, in the + calling function or +* the autorelease pool is restored to a previous state. + +.. admonition:: Rationale + + Rationale: not all memory and resources are managed with reference counts; it + is common for objects to manage private resources in their own, private way. + Typically these resources are completely encapsulated within the object, but + some classes offer their users direct access for efficiency. If ARC is not + aware of methods that return such "interior" pointers, its optimizations can + cause the owning object to be reclaimed too soon. This attribute informs ARC + that it must tread lightly. + + The extension rules are somewhat intentionally vague. The autorelease pool + limit is there to permit a simple implementation to simply retain and + autorelease the receiver. The other limit permits some amount of + optimization. The phrase "derived from" is intended to encompass the results + both of pointer transformations, such as casts and arithmetic, and of loading + from such derived pointers; furthermore, it applies whether or not such + derivations are applied directly in the calling code or by other utility code + (for example, the C library routine ``strchr``). However, the implementation + never need account for uses after a return from the code which calls the + method returning an interior pointer. + +As an exception, no extension is required if the receiver is loaded directly +from a ``__strong`` object with :ref:`precise lifetime semantics +<arc.optimization.precise>`. + +.. admonition:: Rationale + + Implicit autoreleases carry the risk of significantly inflating memory use, + so it's important to provide users a way of avoiding these autoreleases. + Tying this to precise lifetime semantics is ideal, as for local variables + this requires a very explicit annotation, which allows ARC to trust the user + with good cheer. + +.. _arc.misc.c-retainable: + +C retainable pointer types +========================== + +A type is a :arc-term:`C retainable pointer type`` if it is a pointer to +(possibly qualified) ``void`` or a pointer to a (possibly qualifier) ``struct`` +or ``class`` type. + +.. admonition:: Rationale + + ARC does not manage pointers of CoreFoundation type (or any of the related + families of retainable C pointers which interoperate with Objective-C for + retain/release operation). In fact, ARC does not even know how to + distinguish these types from arbitrary C pointer types. The intent of this + concept is to filter out some obviously non-object types while leaving a hook + for later tightening if a means of exhaustively marking CF types is made + available. + +.. _arc.misc.c-retainable.audit: + +Auditing of C retainable pointer interfaces +------------------------------------------- + +:when-revised:`[beginning Apple 4.0, LLVM 3.1]` + +A C function may be marked with the ``cf_audited_transfer`` attribute to +express that, except as otherwise marked with attributes, it obeys the +parameter (consuming vs. non-consuming) and return (retained vs. non-retained) +conventions for a C function of its name, namely: + +* A parameter of C retainable pointer type is assumed to not be consumed + unless it is marked with the ``cf_consumed`` attribute, and +* A result of C retainable pointer type is assumed to not be returned retained + unless the function is either marked ``cf_returns_retained`` or it follows + the create/copy naming convention and is not marked + ``cf_returns_not_retained``. + +A function obeys the :arc-term:`create/copy` naming convention if its name +contains as a substring: + +* either "Create" or "Copy" not followed by a lowercase letter, or +* either "create" or "copy" not followed by a lowercase letter and + not preceded by any letter, whether uppercase or lowercase. + +A second attribute, ``cf_unknown_transfer``, signifies that a function's +transfer semantics cannot be accurately captured using any of these +annotations. A program is ill-formed if it annotates the same function with +both ``cf_audited_transfer`` and ``cf_unknown_transfer``. + +A pragma is provided to facilitate the mass annotation of interfaces: + +.. code-block:: objc + + #pragma clang arc_cf_code_audited begin + ... + #pragma clang arc_cf_code_audited end + +All C functions declared within the extent of this pragma are treated as if +annotated with the ``cf_audited_transfer`` attribute unless they otherwise have +the ``cf_unknown_transfer`` attribute. The pragma is accepted in all language +modes. A program is ill-formed if it attempts to change files, whether by +including a file or ending the current file, within the extent of this pragma. + +It is possible to test for all the features in this section with +``__has_feature(arc_cf_code_audited)``. + +.. admonition:: Rationale + + A significant inconvenience in ARC programming is the necessity of + interacting with APIs based around C retainable pointers. These features are + designed to make it relatively easy for API authors to quickly review and + annotate their interfaces, in turn improving the fidelity of tools such as + the static analyzer and ARC. The single-file restriction on the pragma is + designed to eliminate the risk of accidentally annotating some other header's + interfaces. + +.. _arc.runtime: + +=============== +Runtime support +=============== + +This section describes the interaction between the ARC runtime and the code +generated by the ARC compiler. This is not part of the ARC language +specification; instead, it is effectively a language-specific ABI supplement, +akin to the "Itanium" generic ABI for C++. + +Ownership qualification does not alter the storage requirements for objects, +except that it is undefined behavior if a ``__weak`` object is inadequately +aligned for an object of type ``id``. The other qualifiers may be used on +explicitly under-aligned memory. + +The runtime tracks ``__weak`` objects which holds non-null values. It is +undefined behavior to direct modify a ``__weak`` object which is being tracked +by the runtime except through an +:ref:`objc_storeWeak <arc.runtime.objc_storeWeak>`, +:ref:`objc_destroyWeak <arc.runtime.objc_destroyWeak>`, or +:ref:`objc_moveWeak <arc.runtime.objc_moveWeak>` call. + +The runtime must provide a number of new entrypoints which the compiler may +emit, which are described in the remainder of this section. + +.. admonition:: Rationale + + Several of these functions are semantically equivalent to a message send; we + emit calls to C functions instead because: + + * the machine code to do so is significantly smaller, + * it is much easier to recognize the C functions in the ARC optimizer, and + * a sufficient sophisticated runtime may be able to avoid the message send in + common cases. + + Several other of these functions are "fused" operations which can be + described entirely in terms of other operations. We use the fused operations + primarily as a code-size optimization, although in some cases there is also a + real potential for avoiding redundant operations in the runtime. + +.. _arc.runtime.objc_autorelease: + +``id objc_autorelease(id value);`` +================================== + +*Precondition:* ``value`` is null or a pointer to a valid object. + +If ``value`` is null, this call has no effect. Otherwise, it adds the object +to the innermost autorelease pool exactly as if the object had been sent the +``autorelease`` message. + +Always returns ``value``. + +.. _arc.runtime.objc_autoreleasePoolPop: + +``void objc_autoreleasePoolPop(void *pool);`` +============================================= + +*Precondition:* ``pool`` is the result of a previous call to +:ref:`objc_autoreleasePoolPush <arc.runtime.objc_autoreleasePoolPush>` on the +current thread, where neither ``pool`` nor any enclosing pool have previously +been popped. + +Releases all the objects added to the given autorelease pool and any +autorelease pools it encloses, then sets the current autorelease pool to the +pool directly enclosing ``pool``. + +.. _arc.runtime.objc_autoreleasePoolPush: + +``void *objc_autoreleasePoolPush(void);`` +========================================= + +Creates a new autorelease pool that is enclosed by the current pool, makes that +the current pool, and returns an opaque "handle" to it. + +.. admonition:: Rationale + + While the interface is described as an explicit hierarchy of pools, the rules + allow the implementation to just keep a stack of objects, using the stack + depth as the opaque pool handle. + +.. _arc.runtime.objc_autoreleaseReturnValue: + +``id objc_autoreleaseReturnValue(id value);`` +============================================= + +*Precondition:* ``value`` is null or a pointer to a valid object. + +If ``value`` is null, this call has no effect. Otherwise, it makes a best +effort to hand off ownership of a retain count on the object to a call to +:ref:`objc_retainAutoreleasedReturnValue +<arc.runtime.objc_retainAutoreleasedReturnValue>` for the same object in an +enclosing call frame. If this is not possible, the object is autoreleased as +above. + +Always returns ``value``. + +.. _arc.runtime.objc_copyWeak: + +``void objc_copyWeak(id *dest, id *src);`` +========================================== + +*Precondition:* ``src`` is a valid pointer which either contains a null pointer +or has been registered as a ``__weak`` object. ``dest`` is a valid pointer +which has not been registered as a ``__weak`` object. + +``dest`` is initialized to be equivalent to ``src``, potentially registering it +with the runtime. Equivalent to the following code: + +.. code-block:: objc + + void objc_copyWeak(id *dest, id *src) { + objc_release(objc_initWeak(dest, objc_loadWeakRetained(src))); + } + +Must be atomic with respect to calls to ``objc_storeWeak`` on ``src``. + +.. _arc.runtime.objc_destroyWeak: + +``void objc_destroyWeak(id *object);`` +====================================== + +*Precondition:* ``object`` is a valid pointer which either contains a null +pointer or has been registered as a ``__weak`` object. + +``object`` is unregistered as a weak object, if it ever was. The current value +of ``object`` is left unspecified; otherwise, equivalent to the following code: + +.. code-block:: objc + + void objc_destroyWeak(id *object) { + objc_storeWeak(object, nil); + } + +Does not need to be atomic with respect to calls to ``objc_storeWeak`` on +``object``. + +.. _arc.runtime.objc_initWeak: + +``id objc_initWeak(id *object, id value);`` +=========================================== + +*Precondition:* ``object`` is a valid pointer which has not been registered as +a ``__weak`` object. ``value`` is null or a pointer to a valid object. + +If ``value`` is a null pointer or the object to which it points has begun +deallocation, ``object`` is zero-initialized. Otherwise, ``object`` is +registered as a ``__weak`` object pointing to ``value``. Equivalent to the +following code: + +.. code-block:: objc + + id objc_initWeak(id *object, id value) { + *object = nil; + return objc_storeWeak(object, value); + } + +Returns the value of ``object`` after the call. + +Does not need to be atomic with respect to calls to ``objc_storeWeak`` on +``object``. + +.. _arc.runtime.objc_loadWeak: + +``id objc_loadWeak(id *object);`` +================================= + +*Precondition:* ``object`` is a valid pointer which either contains a null +pointer or has been registered as a ``__weak`` object. + +If ``object`` is registered as a ``__weak`` object, and the last value stored +into ``object`` has not yet been deallocated or begun deallocation, retains and +autoreleases that value and returns it. Otherwise returns null. Equivalent to +the following code: + +.. code-block:: objc + + id objc_loadWeak(id *object) { + return objc_autorelease(objc_loadWeakRetained(object)); + } + +Must be atomic with respect to calls to ``objc_storeWeak`` on ``object``. + +.. admonition:: Rationale + + Loading weak references would be inherently prone to race conditions without + the retain. + +.. _arc.runtime.objc_loadWeakRetained: + +``id objc_loadWeakRetained(id *object);`` +========================================= + +*Precondition:* ``object`` is a valid pointer which either contains a null +pointer or has been registered as a ``__weak`` object. + +If ``object`` is registered as a ``__weak`` object, and the last value stored +into ``object`` has not yet been deallocated or begun deallocation, retains +that value and returns it. Otherwise returns null. + +Must be atomic with respect to calls to ``objc_storeWeak`` on ``object``. + +.. _arc.runtime.objc_moveWeak: + +``void objc_moveWeak(id *dest, id *src);`` +========================================== + +*Precondition:* ``src`` is a valid pointer which either contains a null pointer +or has been registered as a ``__weak`` object. ``dest`` is a valid pointer +which has not been registered as a ``__weak`` object. + +``dest`` is initialized to be equivalent to ``src``, potentially registering it +with the runtime. ``src`` may then be left in its original state, in which +case this call is equivalent to :ref:`objc_copyWeak +<arc.runtime.objc_copyWeak>`, or it may be left as null. + +Must be atomic with respect to calls to ``objc_storeWeak`` on ``src``. + +.. _arc.runtime.objc_release: + +``void objc_release(id value);`` +================================ + +*Precondition:* ``value`` is null or a pointer to a valid object. + +If ``value`` is null, this call has no effect. Otherwise, it performs a +release operation exactly as if the object had been sent the ``release`` +message. + +.. _arc.runtime.objc_retain: + +``id objc_retain(id value);`` +============================= + +*Precondition:* ``value`` is null or a pointer to a valid object. + +If ``value`` is null, this call has no effect. Otherwise, it performs a retain +operation exactly as if the object had been sent the ``retain`` message. + +Always returns ``value``. + +.. _arc.runtime.objc_retainAutorelease: + +``id objc_retainAutorelease(id value);`` +======================================== + +*Precondition:* ``value`` is null or a pointer to a valid object. + +If ``value`` is null, this call has no effect. Otherwise, it performs a retain +operation followed by an autorelease operation. Equivalent to the following +code: + +.. code-block:: objc + + id objc_retainAutorelease(id value) { + return objc_autorelease(objc_retain(value)); + } + +Always returns ``value``. + +.. _arc.runtime.objc_retainAutoreleaseReturnValue: + +``id objc_retainAutoreleaseReturnValue(id value);`` +=================================================== + +*Precondition:* ``value`` is null or a pointer to a valid object. + +If ``value`` is null, this call has no effect. Otherwise, it performs a retain +operation followed by the operation described in +:ref:`objc_autoreleaseReturnValue <arc.runtime.objc_autoreleaseReturnValue>`. +Equivalent to the following code: + +.. code-block:: objc + + id objc_retainAutoreleaseReturnValue(id value) { + return objc_autoreleaseReturnValue(objc_retain(value)); + } + +Always returns ``value``. + +.. _arc.runtime.objc_retainAutoreleasedReturnValue: + +``id objc_retainAutoreleasedReturnValue(id value);`` +==================================================== + +*Precondition:* ``value`` is null or a pointer to a valid object. + +If ``value`` is null, this call has no effect. Otherwise, it attempts to +accept a hand off of a retain count from a call to +:ref:`objc_autoreleaseReturnValue <arc.runtime.objc_autoreleaseReturnValue>` on +``value`` in a recently-called function or something it calls. If that fails, +it performs a retain operation exactly like :ref:`objc_retain +<arc.runtime.objc_retain>`. + +Always returns ``value``. + +.. _arc.runtime.objc_retainBlock: + +``id objc_retainBlock(id value);`` +================================== + +*Precondition:* ``value`` is null or a pointer to a valid block object. + +If ``value`` is null, this call has no effect. Otherwise, if the block pointed +to by ``value`` is still on the stack, it is copied to the heap and the address +of the copy is returned. Otherwise a retain operation is performed on the +block exactly as if it had been sent the ``retain`` message. + +.. _arc.runtime.objc_storeStrong: + +``id objc_storeStrong(id *object, id value);`` +============================================== + +*Precondition:* ``object`` is a valid pointer to a ``__strong`` object which is +adequately aligned for a pointer. ``value`` is null or a pointer to a valid +object. + +Performs the complete sequence for assigning to a ``__strong`` object of +non-block type. Equivalent to the following code: + +.. code-block:: objc + + id objc_storeStrong(id *object, id value) { + value = [value retain]; + id oldValue = *object; + *object = value; + [oldValue release]; + return value; + } + +Always returns ``value``. + +.. _arc.runtime.objc_storeWeak: + +``id objc_storeWeak(id *object, id value);`` +============================================ + +*Precondition:* ``object`` is a valid pointer which either contains a null +pointer or has been registered as a ``__weak`` object. ``value`` is null or a +pointer to a valid object. + +If ``value`` is a null pointer or the object to which it points has begun +deallocation, ``object`` is assigned null and unregistered as a ``__weak`` +object. Otherwise, ``object`` is registered as a ``__weak`` object or has its +registration updated to point to ``value``. + +Returns the value of ``object`` after the call. + -- GitLab