123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385 |
- .. 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; }
- /*
- * Automatic numbering is described in this article:
- * https://dev.opera.com/articles/view/automatic-numbering-with-css-counters/
- */
- /*
- * Automatic numbering for the TOC.
- * This is wrong from the semantics point of view, since it is an ordered
- * list, but uses "ul" tag.
- */
- div#contents.contents.local ul {
- counter-reset: toc-section;
- list-style-type: none;
- }
- div#contents.contents.local ul li {
- counter-increment: toc-section;
- background: none; // Remove bullets
- }
- div#contents.contents.local ul li a.reference:before {
- content: counters(toc-section, ".") " ";
- }
- /* Automatic numbering for the body. */
- body {
- counter-reset: section subsection subsubsection;
- }
- .section h2 {
- counter-reset: subsection subsubsection;
- counter-increment: section;
- }
- .section h2 a.toc-backref:before {
- content: counter(section) " ";
- }
- .section h3 {
- counter-reset: subsubsection;
- counter-increment: subsection;
- }
- .section h3 a.toc-backref:before {
- content: counter(section) "." counter(subsection) " ";
- }
- .section h4 {
- counter-increment: subsubsection;
- }
- .section h4 a.toc-backref:before {
- content: counter(section) "." counter(subsection) "." counter(subsubsection) " ";
- }
- </style>
- .. role:: arc-term
- .. role:: revision
- .. role:: when-revised
- ==============================================
- Objective-C Automatic Reference Counting (ARC)
- ==============================================
- .. contents::
- :local:
- .. _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 macOS, 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, or
- * :when-revised:`[beginning LLVM 3.6]` :revision:`a load from a` ``const``
- :revision:`non-system global variable.`
- 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.
- For loads from ``const`` global variables of :ref:`C retainable pointer type
- <arc.misc.c-retainable>`, it is reasonable to assume that global system
- constants were initialitzed with true constants (e.g. string literals), but
- user constants might have been initialized with something dynamically
- allocated, using a global initializer.
- .. _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.
- When forming a function type, the result type is adjusted so that any
- top-level ownership qualifier is deleted.
- 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>`. Ownership qualifiers
- on return types are dropped because they serve no purpose there except to
- cause spurious problems with overloading and templates.
- 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
- initially applies to that type;
- * otherwise, if the outermost non-array declarator is a pointer
- or block pointer declarator, the qualifier initially applies to
- that type;
- * otherwise the program is ill-formed.
- * If the qualifier is so applied at a position in the declaration
- where the next-innermost declarator is a function declarator, and
- there is an block declarator within that function declarator, then
- the qualifier applies instead to that block declarator and this rule
- is considered afresh beginning from the new position.
- If an ownership qualifier appears on the declarator name, or on the declared
- object, it is applied to the innermost pointer or block-pointer type.
- If an ownership qualifier appears anywhere else in a declarator, it applies to
- the type there.
- .. admonition:: Rationale
- Ownership qualifiers are like ``const`` and ``volatile`` in the sense
- that they may sensibly apply at multiple distinct positions within a
- declarator. However, unlike those qualifiers, there are many
- situations where they are not meaningful, and so we make an effort
- to "move" the qualifier to a place where it will be meaningful. The
- general goal is to allow the programmer to write, say, ``__strong``
- before the entire declaration and have it apply in the leftmost
- sensible place.
- .. _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_reference_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_reference_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 the storage of a ``__strong`` or ``__weak``
- object is not properly initialized before the first managed operation
- is performed on the object, or if the storage of such an object is freed
- or reused before the object has been properly deinitialized. Storage for
- a ``__strong`` or ``__weak`` object may be properly initialized by filling
- it with the representation of a null pointer, e.g. by acquiring the memory
- with ``calloc`` or using ``bzero`` to zero it out. A ``__strong`` or
- ``__weak`` object may be properly deinitialized by assigning a null pointer
- into it. A ``__strong`` object may also be properly initialized
- by copying into it (e.g. with ``memcpy``) the representation of a
- different ``__strong`` object whose storage has been properly initialized;
- doing this properly deinitializes the source object and causes its storage
- to no longer be properly initialized. A ``__weak`` object may not be
- representation-copied in this way.
- These requirements are followed automatically for objects whose
- initialization and deinitialization are under the control of ARC:
- * objects of static, automatic, and temporary storage duration
- * instance variables of Objective-C objects
- * elements of arrays where the array object's initialization and
- deinitialization are under the control of ARC
- * fields of Objective-C struct types where the struct object's
- initialization and deinitialization are under the control of ARC
- * non-static data members of Objective-C++ non-union class types
- * Objective-C++ objects and arrays of dynamic storage duration created
- with the ``new`` or ``new[]`` operators and destroyed with the
- corresponding ``delete`` or ``delete[]`` operator
- They are not followed automatically for these objects:
- * objects of dynamic storage duration created in other memory, such as
- that returned by ``malloc``
- * union members
- .. admonition:: Rationale
- ARC must perform special operations when initializing an object and
- when destroying it. In many common situations, ARC knows when an
- object is created and when it is destroyed and can ensure that these
- operations are performed correctly. Otherwise, however, ARC requires
- programmer cooperation to establish its initialization invariants
- because it is infeasible for ARC to dynamically infer whether they
- are intact. For example, there is no syntactic difference in C between
- an assignment that is intended by the programmer to initialize a variable
- and one that is intended to replace the existing value stored there,
- but ARC must perform one operation or the other. ARC chooses to always
- assume that objects are initialized (except when it is in charge of
- initializing them) because the only workable alternative would be to
- ban all code patterns that could potentially be used to access
- uninitialized memory, and that would be too limiting. In practice,
- this is rarely a problem because programmers do not generally need to
- work with objects for which the requirements are not handled
- automatically.
- Note that dynamically-allocated Objective-C++ arrays of
- nontrivially-ownership-qualified type are not ABI-compatible with non-ARC
- code because the non-ARC code will consider the element type to be 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
- ============
- Within this section, the word :arc-term:`function` will be used to
- refer to any structured unit of code, be it a C function, an
- Objective-C method, or a block.
- This specification describes ARC as performing specific ``retain`` and
- ``release`` operations on retainable object pointers at specific
- points during the execution of a program. These operations make up a
- non-contiguous subsequence of the computation history of the program.
- The portion of this sequence for a particular retainable object
- pointer for which a specific function execution is directly
- responsible is the :arc-term:`formal local retain history` of the
- object pointer. The corresponding actual sequence executed is the
- `dynamic local retain history`.
- However, under certain circumstances, ARC is permitted to re-order and
- eliminate operations in a manner which may alter the overall
- computation history beyond what is permitted by the general "as if"
- rule of C/C++ and the :ref:`restrictions <arc.objects.retains>` on
- the implementation of ``retain`` and ``release``.
- .. admonition:: Rationale
- Specifically, ARC is sometimes permitted to optimize ``release``
- operations in ways which might cause an object to be deallocated
- before it would otherwise be. Without this, it would be almost
- impossible to eliminate any ``retain``/``release`` pairs. For
- example, consider the following code:
- .. code-block:: objc
- id x = _ivar;
- [x foo];
- If we were not permitted in any event to shorten the lifetime of the
- object in ``x``, then we would not be able to eliminate this retain
- and release unless we could prove that the message send could not
- modify ``_ivar`` (or deallocate ``self``). Since message sends are
- opaque to the optimizer, this is not possible, and so ARC's hands
- would be almost completely tied.
- ARC makes no guarantees about the execution of a computation history
- which contains undefined behavior. In particular, ARC makes no
- guarantees in the presence of race conditions.
- ARC may assume that any retainable object pointers it receives or
- generates are instantaneously valid from that point until a point
- which, by the concurrency model of the host language, happens-after
- the generation of the pointer and happens-before a release of that
- object (possibly via an aliasing pointer or indirectly due to
- destruction of a different object).
- .. admonition:: Rationale
- There is very little point in trying to guarantee correctness in the
- presence of race conditions. ARC does not have a stack-scanning
- garbage collector, and guaranteeing the atomicity of every load and
- store operation would be prohibitive and preclude a vast amount of
- optimization.
- ARC may assume that non-ARC code engages in sensible balancing
- behavior and does not rely on exact or minimum retain count values
- except as guaranteed by ``__strong`` object invariants or +1 transfer
- conventions. For example, if an object is provably double-retained
- and double-released, ARC may eliminate the inner retain and release;
- it does not need to guard against code which performs an unbalanced
- release followed by a "balancing" retain.
- .. _arc.optimization.liveness:
- Object liveness
- ---------------
- ARC may not allow a retainable object ``X`` to be deallocated at a
- time ``T`` in a computation history if:
- * ``X`` is the value stored in a ``__strong`` object ``S`` with
- :ref:`precise lifetime semantics <arc.optimization.precise>`, or
- * ``X`` is the value stored in a ``__strong`` object ``S`` with
- imprecise lifetime semantics and, at some point after ``T`` but
- before the next store to ``S``, the computation history features a
- load from ``S`` and in some way depends on the value loaded, or
- * ``X`` is a value described as being released at the end of the
- current full-expression and, at some point after ``T`` but before
- the end of the full-expression, the computation history depends
- on that value.
- .. admonition:: Rationale
- The intent of the second rule is to say that objects held in normal
- ``__strong`` local variables may be released as soon as the value in
- the variable is no longer being used: either the variable stops
- being used completely or a new value is stored in the variable.
- The intent of the third rule is to say that return values may be
- released after they've been used.
- A computation history depends on a pointer value ``P`` if it:
- * performs a pointer comparison with ``P``,
- * loads from ``P``,
- * stores to ``P``,
- * depends on a pointer value ``Q`` derived via pointer arithmetic
- from ``P`` (including an instance-variable or field access), or
- * depends on a pointer value ``Q`` loaded from ``P``.
- Dependency applies only to values derived directly or indirectly from
- a particular expression result and does not occur merely because a
- separate pointer value dynamically aliases ``P``. Furthermore, this
- dependency is not carried by values that are stored to objects.
- .. admonition:: Rationale
- The restrictions on dependency are intended to make this analysis
- feasible by an optimizer with only incomplete information about a
- program. Essentially, dependence is carried to "obvious" uses of a
- pointer. Merely passing a pointer argument to a function does not
- itself cause dependence, but since generally the optimizer will not
- be able to prove that the function doesn't depend on that parameter,
- it will be forced to conservatively assume it does.
- Dependency propagates to values loaded from a pointer because those
- values might be invalidated by deallocating the object. For
- example, given the code ``__strong id x = p->ivar;``, ARC must not
- move the release of ``p`` to between the load of ``p->ivar`` and the
- retain of that value for storing into ``x``.
- Dependency does not propagate through stores of dependent pointer
- values because doing so would allow dependency to outlive the
- full-expression which produced the original value. For example, the
- address of an instance variable could be written to some global
- location and then freely accessed during the lifetime of the local,
- or a function could return an inner pointer of an object and store
- it to a local. These cases would be potentially impossible to
- reason about and so would basically prevent any optimizations based
- on imprecise lifetime. There are also uncommon enough to make it
- reasonable to require the precise-lifetime annotation if someone
- really wants to rely on them.
- Dependency does propagate through return values of pointer type.
- The compelling source of need for this rule is a property accessor
- which returns an un-autoreleased result; the calling function must
- have the chance to operate on the value, e.g. to retain it, before
- ARC releases the original pointer. Note again, however, that
- dependence does not survive a store, so ARC does not guarantee the
- continued validity of the return value past the end of the
- full-expression.
- .. _arc.optimization.object_lifetime:
- No object lifetime extension
- ----------------------------
- If, in the formal computation history of the program, an object ``X``
- has been deallocated by the time of an observable side-effect, then
- ARC must cause ``X`` to be deallocated by no later than the occurrence
- of that side-effect, except as influenced by the re-ordering of the
- destruction of objects.
- .. admonition:: Rationale
- This rule is intended to prohibit ARC from observably extending the
- lifetime of a retainable object, other than as specified in this
- document. Together with the rule limiting the transformation of
- releases, this rule requires ARC to eliminate retains and release
- only in pairs.
- ARC's power to reorder the destruction of objects is critical to its
- ability to do any optimization, for essentially the same reason that
- it must retain the power to decrease the lifetime of an object.
- Unfortunately, while it's generally poor style for the destruction
- of objects to have arbitrary side-effects, it's certainly possible.
- Hence the caveat.
- .. _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.externally_retained:
- Externally-Retained Variables
- -----------------------------
- In some situations, variables with strong ownership are considered
- externally-retained by the implementation. This means that the variable is
- retained elsewhere, and therefore the implementation can elide retaining and
- releasing its value. Such a variable is implicitly ``const`` for safety. In
- contrast with ``__unsafe_unretained``, an externally-retained variable still
- behaves as a strong variable outside of initialization and destruction. For
- instance, when an externally-retained variable is captured in a block the value
- of the variable is retained and released on block capture and destruction. It
- also affects C++ features such as lambda capture, ``decltype``, and template
- argument deduction.
- Implicitly, the implementation assumes that the :ref:`self parameter in a
- non-init method <arc.misc.self>` and the :ref:`variable in a for-in loop
- <arc.misc.enumeration>` are externally-retained.
- Externally-retained semantics can also be opted into with the
- ``objc_externally_retained`` attribute. This attribute can apply to strong local
- variables, functions, methods, or blocks:
- .. code-block:: objc
- @class WobbleAmount;
- @interface Widget : NSObject
- -(void)wobble:(WobbleAmount *)amount;
- @end
- @implementation Widget
- -(void)wobble:(WobbleAmount *)amount
- __attribute__((objc_externally_retained)) {
- // 'amount' and 'alias' aren't retained on entry, nor released on exit.
- __attribute__((objc_externally_retained)) WobbleAmount *alias = amount;
- }
- @end
- Annotating a function with this attribute makes every parameter with strong
- retainable object pointer type externally-retained, unless the variable was
- explicitly qualified with ``__strong``. For instance, ``first_param`` is
- externally-retained (and therefore ``const``) below, but not ``second_param``:
- .. code-block:: objc
- __attribute__((objc_externally_retained))
- void f(NSArray *first_param, __strong NSArray *second_param) {
- // ...
- }
- You can test if your compiler has support for ``objc_externally_retained`` with
- ``__has_attribute``:
- .. code-block:: objc
- #if __has_attribute(objc_externally_retained)
- // Use externally retained...
- #endif
- .. _arc.misc.self:
- ``self``
- --------
- The ``self`` parameter variable of an non-init Objective-C method is considered
- :ref:`externally-retained <arc.misc.externally_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. In an init method, ``self``
- follows the :ref:``init family rules <arc.family.semantics.init>``.
- .. 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 ``objc_externally_retained`` or
- qualifying it with ``__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
- implicitly :ref:`externally-retained <arc.misc.externally_retained>` so that
- objects encountered during the enumeration are not actually retained and
- released.
- .. 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:
- ``void 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
- void objc_storeStrong(id *object, id value) {
- id oldValue = *object;
- value = [value retain];
- *object = value;
- [oldValue release];
- }
- .. [*] This does not imply that a ``__strong`` object of block type is an
- invalid argument to this function. Rather it implies that an ``objc_retain``
- and not an ``objc_retainBlock`` operation will be emitted if the argument is
- a block.
- .. _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.
|