原文地址:http://clang.llvm.org/docs/AutomaticReferenceCounting.html
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.
This document assumes a basic familiarity with C.
Blocks are a C language extension forcreating anonymous functions. Users interact with and transfer blockobjects using block pointers, which arerepresented like a normal pointer. A block may capture values fromlocal variables; when this occurs, memory must be dynamicallyallocated. The initial allocation is done on the stack, but theruntime provides a Block_copy function which, given a blockpointer, 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 itsreference count by 1. The paired function is Block_release,which decreases the reference count by 1 and destroys the object ifthe count reaches zero and is on the heap.
Objective-C is a set of language extensions, significant enough tobe considered a different language. It is a strict superset of C.The extensions can also be imposed on C++, producing a language calledObjective-C++. The primary feature is a single-inheritance objectsystem; we briefly describe the modern dialect.
Objective-C defines a new type kind, collectively calledthe object pointer types. This kind has twonotable builtin members, id and Class; idis the final supertype of all object pointers. The validity ofconversions between object pointer types is not checked at runtime.Users may define classes; each class is atype, and the pointer to that type is an object pointer type. A classmay have a superclass; its pointer type is a subtype of itssuperclass's pointer type. A class has a setof ivars, fields which appear on allinstances of that class. For every class T there's anassociated metaclass; it has no fields, its superclass is themetaclass of T's superclass, and its metaclass is a globalclass. Every class has a global object whose class is theclass's metaclass; metaclasses have no associated type, so pointers tothis object have type Class.
A class declaration (@interface) declares a setof methods. A method has a return type, alist of argument types, and a selector: aname like foo:bar:baz:, where the number of colonscorresponds to the number of formal arguments. A method may be aninstance method, in which case it can be invoked on objects of theclass, or a class method, in which case it can be invoked on objectsof the metaclass. A method may be invoked by providing an object(called the receiver) and a list of formalarguments interspersed with the selector, like so:
[receiver foo: fooArg bar: barArg baz: bazArg]
This looks in the dynamic class of the receiver for a method withthis name, then in that class's superclass, etc., until it findssomething it can execute. The receiver expression
may also bethe name of a class, in which case the actual receiver is the classobject for that class, or (within method definitions) it maybe super, in which case the lookup algorithm starts with thestatic superclass instead of the dynamic class. The actual methodsdynamically found in a class are not those declared in the@interface, but those defined in a separate@implementation declaration; however, when compiling acall, typechecking is done based on the methods declared in the@interface.
Method declarations may also be grouped intoprotocols, which are not inherentlyassociated with any class, but which classes may claim to follow.Object pointer types may be qualified with additional protocols thatthe object is known to support.
Class extensions are collections of ivarsand methods, designed to allow a class's @interface to besplit across multiple files; however, there is still a primaryimplementation file which must see the @interfaces of allclass extensions.Categories allow methods (but not ivars) tobe declared post hoc on an arbitrary class; the methods in thecategory's @implementation will be dynamically added to thatclass'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, andtheir lifetime is manually managed using a reference count. This isdone using two instance methods which all classes are expected toimplement: retain increases the object's reference count by1, whereas release decreases it by 1 and calls the instancemethod dealloc if the count reaches 0. To simplify certainoperations, there is also an autoreleasepool, a thread-local list of objects to call releaseon later; an object can be added to this pool bycalling autorelease on it.
Block pointers may be converted to type id; block objectsare laid out in a way that makes them compatible with Objective-Cobjects. There is a builtin class that all block objects areconsidered to be objects of; this class implements retain byadjusting the reference count, not by calling Block_copy.
ARC is under continual evolution, and this document must be updatedas the language progresses.
If a change increases the expressiveness of the language, forexample by lifting a restriction or by adding new syntax, the changewill be annotated with a revision marker, like so:
ARC applies to Objective-C pointer types, block pointer types, and
[beginning Apple 8.0, LLVM 3.8] BPTRs declared within extern "BCPL"
blocks.
For now, it is sensible to version this document by the releases ofits sole implementation (and its host project), clang.LLVM X.Y
refers to an open-source release of clang from theLLVM project. Apple X.Y
refers to an Apple-provided release ofthe Apple LLVM Compiler. Other organizations that prepare their own,separately-versioned clang releases and wish to maintain similarinformation in this document should send requests to cfe-dev.
If a change decreases the expressiveness of the language, forexample by imposing a new restriction, this should be taken as anoversight in the original specification and something to be avoidedin all versions. Such changes are generally to be avoided.
Automatic Reference Counting implements automatic memory managementfor Objective-C objects and blocks, freeing the programmer from theneed to explicitly insert retains and releases. It does not provide acycle collector; users must explicitly manage the lifetime of theirobjects, breaking cycles manually or with weak or unsafereferences.
ARC may be explicitly enabled with the compilerflag -fobjc-arc. It may also be explicitly disabled with thecompiler flag -fno-objc-arc. The last of these two flagsappearing on the compile line wins
.
If ARC is enabled, __has_feature(objc_arc) will expand to1 in the preprocessor. For more information about __has_feature,see the languageextensions document.
This section describes retainable object pointers, their basicoperations, and the restrictions imposed on their use under ARC. Notein particular that it covers the rules for pointer values(patterns of bits indicating the location of a pointed-to object), notpointerobjects (locations in memory which store pointer values).The rules for objects are covered in the next section.
A retainable object pointer(or retainable pointer
) is a value ofa retainable object pointer type(retainable type
). There are three kinds of retainable objectpointer types:
Other pointer types, such as int* and CFStringRef,are not subject to ARC's semantics and restrictions.
Rationale: We are not at liberty to requireall code to be recompiled with ARC; therefore, ARC must interoperatewith Objective-C code which manages retains and releases manually. Ingeneral, there are three requirements in order for acompiler-supported reference-count system to provide reliableinteroperation:
ownershipis passed between caller and callee, for botharguments and return values. Objective-C methods follow such aconvention very reliably, at least for system libraries on Mac OS X,and functions always pass objects at +0. The C-based APIs for CoreFoundation objects, on the other hand, have much more varied transfersemantics.
The use of __attribute__((NSObject)) typedefs is notrecommended. If it's absolutely necessary to use this attribute, bevery explicit about using the typedef, and do not assume that it willbe preserved by language features like __typeof and C++template argument substitution.
Rationale: any compiler operation whichincidentally strips type sugar
from a type will yield a typewithout the attribute, which may result in unexpectedbehavior.
A retainable object pointer is either a nullpointer or a pointer to a valid object. Furthermore, if it hasblock pointer type and is not null then it must actually be apointer to a block object, and if it has Class type (possiblyprotocol-qualified) then it must actually be a pointer to a classobject. Otherwise ARC does not enforce the Objective-C type system aslong as the implementing methods follow the signature of the statictype. It is undefined behavior if ARC is exposed to an invalidpointer.
For ARC's purposes, a valid object is one with well-behaved
retaining operations. Specifically, the object must be laid out suchthat the Objective-C message send machinery can successfully send itthe following messages:
The behavior of these methods is constrained in the following ways.The term high-level semantics is anintentionally vague term; the intent is that programmers mustimplement these methods in a way such that the compiler, modifyingcode in ways it deems safe according to these constraints, will notviolate their requirements. For example, if the user puts loggingstatements in retain, they should not be surprised if thosestatements are executed more or less often depending on optimizationsettings. These constraints are not exhaustive of the optimizationopportunities: values held in local variables are subject toadditional restrictions, described later in this document.
It is undefined behavior if a computation history featuring a sendof retain followed by a send of release to the sameobject, with no intervening release on that object, is notequivalent under the high-level semantics to a computationhistory in which these sends are removed. Note that this implies thatthese methods may not raise exceptions.
It is undefined behavior if a computation history features any usewhatsoever of an object following the completion of a sendof release that is not preceded by a send of retainto the same object.
The behavior of autorelease must be equivalent to sendingrelease when one of the autorelease pools currently in scopeis popped. It may not throw an exception.
When the semantics call for performing one of these operations on aretainable object pointer, if that pointer is null then theeffect is a no-op.
All of the semantics described in this document are subject toadditional optimization rules which permitthe removal or optimization of operations based on local knowledge ofdata flow. The semantics describe the high-level behaviors that thecompiler implements, not an exact sequence of operations that aprogram will be compiled into.
In general, ARC does not perform retain or release operations whensimply using a retainable object pointer as an operand within anexpression. This includes:
Rationale: while this might seemuncontroversial, it is actually unsafe when multiple expressions areevaluated in parallel
, as with binary operators and calls,because (for example) one expression might load from an object whileanother writes to it. However, C and C++ already call this undefinedbehavior because the evaluations are unsequenced, and ARC simplyexploits that here to avoid needing to retain arguments across a largenumber of calls.
The remainder of this section describes exceptions to these rules,how those exceptions are detected, and what those exceptions implysemantically.
A function or method parameter of retainable object pointer typemay be marked as consumed, signifying thatthe callee expects to take ownership of a +1 retain count. This isdone by adding the ns_consumed attribute to the parameterdeclaration, like so:
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, notthe type of the parameter. It controls only how the argument ispassed and received.
When passing such an argument, ARC retains the argument prior tomaking the call.
When receiving such an argument, ARC releases the argument at theend of the function, subject to the usual optimizations for localvalues.
Rationale: this formalizes direct transfersof ownership from a caller to a callee. The most common scenario hereis passing the self parameter to init, but it isuseful to generalize. Typically, local optimization will remove anyextra retains and releases: on the caller side the retain will bemerged with a +1 source, and on the callee side the release will berolled into the initialization of the parameter.
The implicit self parameter of a method may be marked asconsumed by adding __attribute__((ns_consumes_self)) to themethod declaration. Methods in the initfamily are treated as if they were implicitlymarked with this attribute.
It is undefined behavior if an Objective-C message send to a methodwith ns_consumed parameters (other than self) is made with anull receiver. It is undefined behavior if the method to which anObjective-C message send statically resolves to has a different setof ns_consumed parameters than the method it dynamicallyresolves to. It is undefined behavior if a block or function call ismade through a static type with a different set of ns_consumedparameters than the implementation of the called block or function.
Rationale: consumed parameters with nullreceiver are a guaranteed leak. Mismatches with consumed parameterswill cause over-retains or over-releases, depending on the direction.The rule about function calls is really just an application of theexisting C/C++ rule about calling functions through an incompatiblefunction type, but it's useful to state it explicitly.
A function or method which returns a retainable object pointer typemay be marked as returning a retained value, signifying that thecaller expects to take ownership of a +1 retain count. This is doneby adding the ns_returns_retained attribute to the function ormethod declaration, like so:
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 thevalue at the point of evaluation of the return statement, beforeleaving all local scopes.
When receiving a return result from such a function or method, ARCreleases the value at the end of the full-expression it is containedwithin, subject to the usual optimizations for local values.
Rationale: this formalizes direct transfers ofownership from a callee to a caller. The most common scenario thismodels is the retained return from init, alloc,new, and copy methods, but there are other cases inthe frameworks. After optimization there are typically no extraretains and releases required.
Methods inthe alloc, copy, init, mutableCopy,and new families are implicitly marked__attribute__((ns_returns_retained)). This may be suppressedby explicitly marking themethod __attribute__((ns_returns_not_retained)).
It is undefined behavior if the method to which an Objective-Cmessage send statically resolves has different retain semantics on itsresult from the method it dynamically resolves to. It is undefinedbehavior if a block or function call is made through a static typewith different retain semantics on its result from the implementationof the called block or function.
Rationale: Mismatches with returned resultswill cause over-retains or over-releases, depending on the direction.Again, the rule about function calls is really just an application ofthe existing C/C++ rule about calling functions through anincompatible function type.
A method or function which returns a retainable object type butdoes not return a retained value must ensure that the object isstill valid across the return boundary.
When returning from such a function or method, ARC retains thevalue at the point of evaluation of the return statement, then leavesall local scopes, and then balances out the retain while ensuring thatthe value lives across the call boundary. In the worst case, this mayinvolve an autorelease, but callers must not assume that thevalue is actually in the autorelease pool.
ARC performs no extra mandatory work on the caller side, althoughit may elect to do something to shorten the lifetime of the returnedvalue.
Rationale: it is common in non-ARC code to notreturn an autoreleased value; therefore the convention does not forceeither path. It is convenient to not be required to do unnecessaryretains and autoreleases; this permits optimizations such as elidingretain/autoreleases when it can be shown that the original pointerwill still be valid at the point of return.
A method or function may be markedwith __attribute__((ns_returns_autoreleased)) to indicatethat it returns a pointer which is guaranteed to be valid at least aslong as the innermost autorelease pool. There are no additionalsemantics enforced in the definition of such a method; it merelyenables optimizations in callers.
A bridged cast is a C-style castannotated with one of three keywords:
These casts are required in order to transfer objects in and out ofARC control; see the rationale in the sectionon conversion of retainableobject pointers.
Using a __bridge_retained or __bridge_transfercast purely to convince ARC to emit an unbalanced retain or release,respectively, is poor form.
In general, a program which attempts to implicitly or explicitlyconvert a value of retainable object pointer type to anynon-retainable type, or vice-versa, is ill-formed. For example, anObjective-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 bridgedcasts may be used to perform these conversions wherenecessary.
Rationale: we cannot ensure the correctmanagement of the lifetime of objects if they may be freely passedaround as unmanaged types. The bridged casts are provided so that theprogrammer may explicitly describe whether the cast transfers controlinto or out of ARC.
However, the following exceptions apply.
[beginning Apple 4.0, LLVM 3.1] 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 atype other than a retainable object pointer type is ill-formed, asdiscussed above, unless the operand of the cast has a syntactic formwhich is known retained, known unretained, or knownretain-agnostic.
An expression is known retain-agnostic ifit is:
An expression is known unretained if itis an rvalue of C retainablepointer type and it is:
An expression is known retained if it isan rvalue of C retainable pointer typeand it is:
Furthermore:
If the cast operand is known retained, the conversion is treated asa __bridge_transfer cast. If the cast operand is knownunretained or known retain-agnostic, the conversion is treated asa __bridge cast.
Rationale: Bridging casts are annoying.Absent the ability to completely automate the management of CFobjects, however, we are left with relatively poor attempts to reducethe need for a glut of explicit bridges. Hence these rules.
We've so far consciously refrained from implicitly turning retainedCF results from function calls into __bridge_transfer casts.The worry is that some code patterns — for example, creating aCF value, assigning it to an ObjC-typed local, and thencalling CFRelease when done — are a bit too likely tobe accidentally accepted, leading to mysterious behavior.
[beginning Apple 4.0, LLVM 3.1]
If an expression of retainable object pointer type is explicitlycast to a C retainable pointer type,the program is ill-formed as discussed above unless the result isimmediately used:
Rationale: Consumed parameters are left outbecause ARC would naturally balance them with a retain, which wasjudged too treacherous. This is in part because several of the mostcommon consuming functions are in the Release family, and itwould be quite unfortunate for explicit releases to be silentlybalanced out in this way.
This section describes the behavior of objects ofretainable object pointer type; that is, locations in memory whichstore retainable object pointers.
A type is a retainable object owner typeif it is a retainable object pointer type or an array type whoseelement type is a retainable object owner type.
An ownership qualifier is a typequalifier which applies only to retainable object owner types. An array type isownership-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 qualifierto a type which is already ownership-qualified, even if it is the samequalifier. There is a single exception to this rule: an ownership qualifier may be applied to a substituted template type parameter, which overrides theownership qualifier provided by the template argument.
Except as described underthe inference rules, a program isill-formed if it attempts to form a pointer or reference type to aretainable object owner type which lacks an ownership qualifier.
Rationale: these rules, together with theinference rules, ensure that all objects and lvalues of retainableobject pointer type have an ownership qualifier. The ability to override an ownership qualifier during template substitution is required to counteract the inference of __strong for template type arguments.
There are four ownership qualifiers:
A type is nontrivially ownership-qualifiedif it is qualified with __autoreleasing, __strong, or__weak.
The names of the ownership qualifiers are reserved for theimplementation. A program may not assume that they are or are notimplemented with macros, or what those macros expand to.
An ownership qualifier may be written anywhere that any other typequalifier may be written.
If an ownership qualifier appears inthe declaration-specifiers, the following rules apply:
If an ownership qualifier appears on the declarator name, or on thedeclared object, it is applied to outermost pointer or block-pointertype.
If an ownership qualifier appears anywhere else in a declarator, itapplies to the type there.
A property of retainable object pointer type may have ownership.If the property's type is ownership-qualified, then the property hasthat ownership. If the property has one of the following modifiers,then the property has the corresponding ownership. A property isill-formed if it has conflicting sources of ownership, or if it hasredundant ownership modifiers, or if it has __autoreleasingownership.
With the exception of weak, these modifiers are availablein non-ARC modes.
A property's specified ownership is preserved in its metadata, butotherwise the meaning is purely conventional unless the property issynthesized. If a property is synthesized, then theassociated instance variable is theinstance variable which is named, possibly implicitly, by the@synthesize declaration. If the associated instance variablealready exists, then its ownership qualification must equal theownership of the property; otherwise, the instance variable is createdwith that ownership qualification.
A property of retainable object pointer type which is synthesizedwithout a source of ownership has the ownership of its associatedinstance variable, if it already exists; otherwise,[beginning Apple 3.1,LLVM 3.1] its ownership is implicitly strong.Prior to this revision, it was ill-formed to synthesize such aproperty.
Rationale: using strong by defaultis safe and consistent with the generic ARC rule aboutinferring ownership. Itis, unfortunately, inconsistent with the non-ARC rule which statesthat such properties are implicitly assign. However, thatrule is clearly untenable in ARC, since it leads to default-unsafecode. The main merit to banning the properties is to avoid confusionwith non-ARC practice, which did not ultimately strike us assufficient to justify requiring extra syntax and (more importantly)forcing novices to understand ownership rules just to declare aproperty when the default is so reasonable. Changing the rule awayfrom non-ARC practice was acceptable because we had conservativelybanned the synthesis in order to give ourselves exactly thisleeway.
Applying __attribute__((NSObject)) to a property not ofretainable object pointer type has the same behavior it does outsideof ARC: it requires the property type to be some sort of pointer andpermits the use of modifiers other than assign. Thesemodifiers only affect the synthesized getter and setter; directaccesses to the ivar (even if synthesized) still have primitivesemantics, and the value in the ivar will not be automaticallyreleased during deallocation.
There are five managed operations whichmay be performed on an object of retainable object pointer type. Eachqualifier specifies different semantics for each of these operations.It is still undefined behavior to access an object outside of itslifetime.
A load or store with primitive semantics
has the samesemantics as the respective operation would have on an void*lvalue with the same alignment and non-ownership qualification.
Reading occurs when performing alvalue-to-rvalue conversion on an object lvalue.
Assignment occurs when evaluatingan assignment operator. The semantics vary based on the qualification:
Initialization occurs when an object'slifetime begins, which depends on its storage duration.Initialization proceeds in two stages:
Destruction occurs when an object'slifetime ends. In all cases it is semantically equivalent toassigning a null pointer to the object, with the proviso that ofcourse the object cannot be legally read after the object's lifetimeends.
Moving occurs in specific situationswhere an lvalue is moved from
, meaning that its current pointeewill be used but the object may be left in a different (but stillvalid) state. This arises with __block variables and rvaluereferences in C++. For __strong lvalues, moving is equivalentto loading the lvalue with primitive semantics, writing a null pointerto it with primitive semantics, and then releasing the result of theload at the end of the current full-expression. For all otherlvalues, moving is equivalent to reading the object.
It is explicitly permitted for Objective-C classes to notsupport __weak references. It is undefined behavior toperform an operation with weak assignment semantics with a pointer toan Objective-C object whose class does not support __weakreferences.
Rationale: historically, it has beenpossible for a class to provide its own reference-count implementationby overriding retain, release, etc. However, weakreferences to an object require coordination with its class'sreference-count implementation because, among other things, weak loadsand stores must be atomic with respect to the final release.Therefore, existing custom reference-count implementations willgenerally not support weak references without additional effort. Thisis unavoidable without breaking binary compatibility.
A class may indicate that it does not support weak references byproviding the objc_arc_weak_unavailable attribute on theclass's interface declaration. A retainable object pointer typeis weak-unavailable if is a pointer to an(optionally protocol-qualified) Objective-C class Twhere T or one of its superclasses hasthe objc_arc_weak_unavailable attribute. A program isill-formed if it applies the __weak ownership qualifier to aweak-unavailable type or if the value operand of a weak assignmentoperation has a weak-unavailable type.
A program is ill-formed if it declares an __autoreleasingobject of non-automatic storage duration. A program is ill-formedif it captures an __autoreleasing object in a block or,unless by reference, in a C++11 lambda.
Rationale: autorelease pools are tied to thecurrent thread and scope by their nature. While it is possible tohave temporary objects whose instance variables are filled withautoreleased objects, there is no way that ARC can provide any sort ofsafety guarantee there.
It is undefined behavior if a non-null pointer is assigned toan __autoreleasing object while an autorelease pool is inscope and then that object is read after the autorelease pool's scopeis left.
A program is ill-formed if an expression of type T* isconverted, explicitly or implicitly, to the type U*,where T and U have different ownershipqualification, unless:
The analogous rule applies to T& and U& inObjective-C++.
Rationale: these rules provide a reasonablelevel of type-safety for indirect pointers, as long as the underlyingmemory is not deallocated. The conversion to const__unsafe_unretained is permitted because the semantics of readsare equivalent across all these ownership semantics, and that's a veryuseful and common pattern. The interconversion with void* isuseful for allocating memory or otherwise escaping the type system,but use it carefully. reinterpret_cast is considered to bean obvious enough sign of taking responsibility for anyproblems.
It is undefined behavior to access an ownership-qualified objectthrough an lvalue of a differently-qualified type, except that anynon-__weak object may be read throughan __unsafe_unretained lvalue.
It is undefined behavior if a managed operation is performed ona __strong or __weak object without a guarantee thatit contains a primitive zero bit-pattern, or if the storage for suchan object is freed or reused without the object being first assigned anull pointer.
Rationale: ARC cannot differentiate betweenan assignment operator which is intended to initialize
dynamicmemory and one which is intended to potentially replace a value.Therefore the object's pointer must be valid before letting ARC at it.Similarly, C and Objective-C do not provide any language hooks fordestroying objects held in dynamic memory, so it is the programmer'sresponsibility to avoid leaks (__strong objects) andconsistency errors (__weak objects).
These requirements are followed automatically in Objective-C++ whencreating objects of retainable object owner type with newor new[] and destroying them with delete,delete[], or a pseudo-destructor expression. Note thatarrays of nontrivially-ownership-qualified type are not ABI compatiblewith non-ARC code because the element type is non-POD: such arraysthat are new[]'d in ARC translation units cannotbe delete[]'d in non-ARC translation units andvice-versa.
If the argument passed to a parameter of typeT __autoreleasing * has type U oq *,where oq is an ownership qualifier, then the argument is acandidate for pass-by-writeback if:
For purposes of overload resolution, an implicit conversionsequence requiring a pass-by-writeback is always worse than animplicit conversion sequence not requiring a pass-by-writeback.
The pass-by-writeback is ill-formed if the argument expression doesnot have a legal form:
Rationale: the restriction in the form ofthe argument serves two purposes. First, it makes it impossible topass the address of an array to the argument, which serves to protectagainst an otherwise serious risk of mis-inferring an array
argument as an out-parameter. Second, it makes it much less likelythat the user will see confusing aliasing problems due to theimplementation, below, where their store to the writeback temporary isnot immediately seen in the original argument variable.
A pass-by-writeback is evaluated as follows:
Rationale: this is all admittedlyconvoluted. In an ideal world, we would see that a local variable isbeing passed to an out-parameter and retroactively modify its type tobe __autoreleasing rather than __strong. This wouldbe remarkably difficult and not always well-founded under the C typesystem. However, it was judged unacceptably invasive to requireprogrammers to write __autoreleasing on all the variablesthey intend to use for out-parameters. This was the least badsolution.
A program is ill-formed if it declares a member of a C struct orunion to have a nontrivially ownership-qualified type.
Rationale: the resulting type would benon-POD in the C++ sense, but C does not give us very good languagetools for managing the lifetime of aggregates, so it is moreconvenient to simply forbid them. It is still possible to manage thiswith a void* or an __unsafe_unretainedobject.
This restriction does not apply in Objective-C++. However,nontrivally ownership-qualified types are considered non-POD: in C++11terms, they are not trivially default constructible, copyconstructible, move constructible, copy assignable, move assignable,or destructible. It is a violation of C++'s One Definition Rule to usea class outside of ARC that, under ARC, would have a nontriviallyownership-qualified member.
Rationale: unlike in C, we can express allthe necessary ARC semantics for ownership-qualified subobjects assuboperations of the (default) special member functions for the class.These functions then become non-trivial. This has the non-obviousresult that the class will have a non-trivial copy constructor andnon-trivial destructor; if this would not normally be true outside ofARC, objects of the type will be passed and returned in anABI-incompatible manner.
If an object is declared with retainable object owner type, butwithout an explicit ownership qualifier, its type is implicitlyadjusted to have __strong qualification.
As a special case, if the object's base type is Class(possibly protocol-qualified), the type is adjusted tohave __unsafe_unretained qualification instead.
If a function or method parameter has type T*, whereT is an ownership-unqualified retainable object pointer type,then:
Rationale: __autoreleasing existsmostly for this case, the Cocoa convention for out-parameters. Sincea pointer to const is obviously not an out-parameter, weinstead use a type more useful for passing arrays. If the userinstead intends to pass in a mutable array, inferring__autoreleasing is the wrong thing to do; this directs someof the caution in the following rules about writeback.
Such a type written anywhere else would be ill-formed by thegeneral rule requiring ownership qualifiers.
This rule does not apply in Objective-C++ if a parameter's type isdependent in a template pattern and is only instantiated toa type which would be a pointer to an unqualified retainable objectpointer type. Such code is still ill-formed.
Rationale: the convention is very unlikelyto be intentional in template code.
If a template argument for a template type parameter is anretainable object owner type that does not have an explicit ownershipqualifier, it is adjusted to have __strongqualification. This adjustment occurs regardless of whether thetemplate argument was deduced or explicitly specified.
Rationale: __strong is a useful default for containers (e.g., std::vector
An Objective-C method may fall into a methodfamily, which is a conventional set of behaviors ascribed to itby the Cocoa conventions.
A method is in a certain method family if:
A selector is in a certain selector family if, ignoring any leadingunderscores, the first component of the selector either consistsentirely of the name of the method family or it begins with that namefollowed by a character other than a lowercase letter. Forexample, _perform:with: and performWith: would fallinto the perform family (if we recognized one),but performing:with would not.
The families and their added restrictions are:
Rationale: there are a fair number of existingmethods with init-like selectors which nonetheless don'tfollow the init conventions. Typically these are eitheraccidental naming collisions or helper methods called duringinitialization. Because of the peculiar retain/release behaviorof init methods, it's very important not to treat thesemethods as init methods if they aren't meant to be. It wasfelt that implicitly defining these methods out of the family based onthe exact relationship between the return type and the declaring classwould be much too subtle and fragile. Therefore we identify a smallnumber of legitimate-seeming return types and call everything else anerror. This serves the secondary purpose of encouraging programmersnot to accidentally give methods names in the init family.
Note that a method with an init-family selector whichreturns a non-Objective-C type (e.g. void) is perfectlywell-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 methodfamily.
A method may be annotated with the objc_method_familyattribute to precisely control which method family it belongs to. Ifa method in an @implementation does not have this attribute,but there is a method declared in the corresponding @interfacethat 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 ifit would otherwise be considered to have one based on its selector andtype. Otherwise, family must be oneof alloc, copy, init,mutableCopy, or new, in which case the method isconsidered to belong to the corresponding family regardless of itsselector. It is an error if a method that is explicitly added to afamily in this way does not meet the requirements of the family otherthan the selector naming convention.
Rationale: the rules codified in this documentdescribe the standard conventions of Objective-C. However, as theseconventions have not heretofore been enforced by an unforgivingmechanical system, they are only imperfectly kept, especially as theyhaven't always even been precisely defined. While it is possible todefine low-level ownership semantics with attributes likens_returns_retained, this attribute allows the user tocommunicate semantic intent, which is of use both to ARC (which, e.g.,treats calls to init specially) and the static analyzer.
A method's membership in a method family may imply non-standardsemantics for its parameters and return type.
Methods in the alloc, copy, mutableCopy,and new families — that is, methods in all thecurrently-defined families except init — implicitlyreturn a retainedobject as if they were annotated withthe ns_returns_retained attribute. This can be overridden byannotating the method with either ofthe ns_returns_autoreleased orns_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 retained objects. This can be overridden by annotating the property with ns_returns_not_retained attribute.
Methods in the init family implicitlyconsume their selfparameter and return aretained object. Neither of these properties can be alteredthrough attributes.
A call to an init method with a receiver that is eitherself (possibly parenthesized or casted) or super iscalled a delegate init call. It is an errorfor a delegate init call to be made except from an initmethod, and excluding blocks within such methods.
As an exception to the usual rule, thevariable self is mutable in an init method and hasthe usual semantics for a __strong variable. However, it isundefined behavior and the program is ill-formed, no diagnosticrequired, if an init method attempts to use the previousvalue of self after the completion of a delegate init call.It is conventional, but not required, for an init method toreturn self.
It is undefined behavior for a program to cause two or more callsto init methods on the same object, except thateach init method invocation may perform at most one delegateinit call.
Certain methods are candidates to have relatedresult types:
If the formal result type of such a method is id orprotocol-qualified id, or a type equal to the declaring classor a superclass, then it is said to have a related result type. Inthis case, when invoked in an explicit message send, it is assumed toreturn a type related to the type of the receiver:
This is a new rule of the Objective-C language and applies outsideof ARC.
Rationale: ARC's automatic code emission ismore prone than most code to signature errors, i.e. errors where acall was emitted against one method signature, but the implementingmethod has an incompatible signature. Having more precise typeinformation helps drastically lower this risk, as well as catchinga number of latent bugs.
ARC applies aggressive rules for the optimization of localbehavior. These rules are based around a core assumption oflocal balancing: that other code willperform retains and releases as necessary (and only as necessary) forits own safety, and so the optimizer does not need to consider globalproperties of the retain and release sequence. For example, if aretain and release immediately bracket a call, the optimizer candelete the retain and release on the assumption that the calledfunction will not do a constant number of unmotivated releasesfollowed by a constant number of balancing
retains, such thatthe local retain/release pair is the only thing preventing the calledfunction from ending up with a dangling reference.
The optimizer assumes that when a new value enters local control,e.g. from a load of a non-local object or as the result of a functioncall, it is instaneously valid. Subsequently, a retain and release ofa value are necessary on a computation path only if there is a use ofthat value before the release and after any operation which mightcause a release of the value (including indirectly or non-locally),and only if the value is not demonstrably already retained.
The complete optimization rules are quite complicated, but it wouldstill be useful to document them here.
In general, ARC maintains an invariant that a retainable objectpointer held in a __strong object will be retained for thefull formal lifetime of the object. Objects subject to this invarianthave precise lifetime semantics.
By default, local variables of automatic storage duration do nothave precise lifetime semantics. Such objects are simply strongreferences which hold values of retainable object pointer type, andthese values are still fully subject to the optimizations on valuesunder local control.
Rationale: applying these precise-lifetimesemantics strictly would be prohibitive. Many useful optimizationsthat might theoretically decrease the lifetime of an object would berendered impossible. Essentially, it promises too much.
A local variable of retainable object owner type and automaticstorage duration may be annotated with the objc_precise_lifetimeattribute to indicate that it should be considered to be an objectwith precise lifetime semantics.
Rationale: nonetheless, it is sometimesuseful 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 beuncommon enough that the syntactic weight of explicitly requestingthese semantics will not be burdensome, and may even make the codeclearer.
A program is ill-formed if it contains a method definition, messagesend, or @selector expression for any of the followingselectors:
Rationale: retainCount is bannedbecause ARC robs it of consistent semantics. The others were bannedafter weighing three options for how to deal with message sends:
Honoring them would work out very poorly if a programmernaively or accidentally tried to incorporate code written for manualretain/release code into an ARC program. At best, such code would dotwice as much work as necessary; quite frequently, however, ARC andthe explicit code would both try to balance the same retain, leadingto crashes. The cost is losing the ability to perform unrooted
retains, i.e. retains not logically corresponding to a strongreference in the object graph.
Ignoring them would badly violate user expectations about theircode. While it would make it easier to develop code simultaneouslyfor ARC and non-ARC, there is very little reason to do so except forcertain library developers. ARC and non-ARC translation units sharean execution model and can seamlessly interoperate. Within atranslation unit, a developer who faithfully maintains their code innon-ARC mode is suffering all the restrictions of ARC for zerobenefit, while a developer who isn't testing the non-ARC mode islikely to be unpleasantly surprised if they try to go back to it.
Banning them has the disadvantage of making it very awkwardto migrate existing code to ARC. The best answer to that, given anumber of other changes and restrictions in ARC, is to provide aspecialized tool to assist users in that migration.
Implementing these methods was banned because they are too integralto the semantics of ARC; many tricks which worked tolerably undermanual reference counting will misbehave if ARC performs an ephemeralextra retain or two. If absolutely required, it is still possible toimplement them in non-ARC code, for example in a category; theimplementations must obey the semanticslaid out elsewhere in this document.
A program is ill-formed if it contains a message sendor @selector expression for the selector dealloc.
Rationale: there are no legitimate reasonsto call dealloc directly.
A class may provide a method definition for an instance methodnamed dealloc. This method will be called after the finalrelease of the object but before it is deallocated or any ofits instance variables are destroyed. The superclass's implementationof dealloc will be called automatically when the methodreturns.
Rationale: even though ARC destroys instancevariables automatically, there are still legitimate reasons to writea dealloc method, such as freeing non-retainable resources.Failing to call [super dealloc] in such a method is nearlyalways a bug. Sometimes, the object is simply trying to preventitself from being destroyed, but dealloc is really far toolate for the object to be raising such objections. Somewhat morelegitimately, an object may have been pool-allocated and should not bedeallocated with free; for now, this can only be supportedwith a dealloc implementation outside of ARC. Such animplementation must be very careful to do all the other workthat NSObject's dealloc would, which is outside thescope of this document to describe.
The instance variables for an ARC-compiled class will be destroyedat some point after control enters the dealloc method for theroot class of the class. The ordering of the destruction of instancevariables is unspecified, both within a single class and betweensubclasses and superclasses.
Rationale: the traditional, non-ARC patternfor destroying instance variables is to destroy them immediatelybefore calling [super dealloc]. Unfortunately, messagesends from the superclass are quite capable of reaching methods in thesubclass, and those methods may well read or write to those instancevariables. Making such message sends from dealloc is generallydiscouraged, since the subclass may well rely on other invariants thatwere broken during dealloc, but it's not so inescapablydangerous that we felt comfortable calling it undefined behavior.Therefore we chose to delay destroying the instance variables to apoint at which message sends are clearly disallowed: the point atwhich 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 anobject whose deallocation will trigger a side-effect which must becarefully ordered with respect to the destruction of the super class.Such code violates the design principle that semantically importantbehavior should be explicit. A simple fix is to clear the instancevariable manually during dealloc; a more holistic solution isto move semantically important side-effects out ofdealloc and into a separate teardown phase which can rely onworking with well-formed objects.
To simplify the use of autorelease pools, and to bring them underthe control of the compiler, a new kind of statement is available inObjective-C. It is written @autoreleasepool followed bya compound-statement, i.e. by a new scope delimited by curlybraces. Upon entry to this block, the current state of theautorelease pool is captured. When the block is exited normally,whether by fallthrough or directed control flow (suchas return or break), the autorelease pool isrestored to the saved state, releasing all the objects in it. Whenthe 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 theNSAutoreleasePool class.
Rationale: autorelease pools are clearlyimportant for the compiler to reason about, but it is far too much toexpect the compiler to accurately reason about control dependenciesbetween two calls. It is also very easy to accidentally forget todrain an autorelease pool when using the manual API, and this cansignificantly inflate the process's high-water-mark. The introductionof a new scope is unfortunate but basically required for saneinteraction with the rest of the language. Not draining the poolduring an unwind is apparently required by the Objective-C exceptionsimplementation.
The self parameter variable of an Objective-C method isnever actually retained by the implementation. It is undefinedbehavior, or at least dangerous, to cause an object to be deallocatedduring a message send to that object.
To make this safe, for Objective-C instance methods self isimplicitly const unless the method is in the init family. Further, selfis always implicitly const within a class method.
Rationale: the cost ofretaining self in all methods was found to be prohibitive, asit tends to be live across calls, preventing the optimizer fromproving that the retain and release are unnecessary — for goodreason, as it's quite possible in theory to cause an object to bedeallocated 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 thisretain/release pair otherwise (as there is for other parameters by,say, making the variable __unsafe_unretained), we chose tomake this optimizing assumption and shift some amount of risk to theuser.
If a variable is declared in the condition of an Objective-C fastenumeration loop, and the variable has no explicit ownershipqualifier, then it is qualified with const __strong andobjects encountered during the enumeration are not actuallyretained.
Rationale: this is an optimization madepossible because fast enumeration loops promise to keep the objectsretained during enumeration, and the collection itself cannot besynchronously modified. It can be overridden by explicitly qualifyingthe variable with __strong, which will make the variablemutable again and cause the loop to retain the objects itencounters.
The implicit const capture variables created whenevaluating a block literal expression have the same ownershipsemantics as the local variables they capture. The capture isperformed by reading from the captured variable and initializing thecapture variable with that value; the capture variable is destroyedwhen the block literal is, i.e. at the end of the enclosing scope.
The inference rules applyequally to __block variables, which is a shift in semanticsfrom non-ARC, where __block variables did not implicitlyretain during capture.
__block variables of retainable object owner type aremoved off the stack by initializing the heap copy with the result ofmoving from the stack copy.
With the exception of retains done as part of initializinga __strong parameter variable or reading a __weakvariable, whenever these semantics call for retaining a value ofblock-pointer type, it has the effect of a Block_copy. Theoptimizer may remove such copies when it sees that the result isused only as an argument to a call.
By default in Objective C, ARC is not exception-safe for normalreleases:
A program may be compiled with the option-fobjc-arc-exceptions in order to enable these, or with theoption -fno-objc-arc-exceptions to explicitly disable them,with the last such argument winning
.
Rationale: the standard Cocoa convention isthat exceptions signal programmer error and are not intended to berecovered from. Making code exceptions-safe by default would imposesevere runtime and code size penalties on code that typically does notactually care about exceptions safety. Therefore, ARC-generated codeleaks by default on exceptions, which is just fine if the process isgoing to be immediately terminated anyway. Programs which do careabout recovering from exceptions should enable the option.
In Objective-C++, -fobjc-arc-exceptions is enabled bydefault.
Rationale: C++ already introduces pervasiveexceptions-cleanup code of the sort that ARC introduces. C++programmers who have not already disabled exceptions are much morelikely to actual require exception-safety.
ARC does end the lifetimes of __weak objects when anexception terminates their scope unless exceptions are disabled in thecompiler.
Rationale: the consequence of alocal __weak object not being destroyed is very likely to becorruption of the Objective-C runtime, so we want to be safer here.Of course, potentially massive leaks are about as likely to take downthe process as this corruption is if the program does try to recoverfrom exceptions.
An Objective-C method returning a non-retainable pointer may beannotated with the objc_returns_inner_pointer attribute toindicate that it returns a handle to the internal data of an object,and that this reference will be invalidated if the object isdestroyed. When such a message is sent to an object, the object'slifetime will be extended until at least the earliest of:
Rationale: not all memory and resources aremanaged with reference counts; it is common for objects to manageprivate resources in their own, private way. Typically theseresources are completely encapsulated within the object, but someclasses offer their users direct access for efficiency. If ARC is notaware of methods that return such interior
pointers, itsoptimizations 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. Theautorelease pool limit is there to permit a simple implementation tosimply retain and autorelease the receiver. The other limit permitssome amount of optimization. The phrase derived from
isintended to encompass the results both of pointer transformations,such as casts and arithmetic, and of loading from such derivedpointers; furthermore, it applies whether or not such derivations areapplied directly in the calling code or by other utility code (forexample, the C library routine strchr). However, theimplementation never need account for uses after a return from thecode which calls the method returning an interior pointer.
As an exception, no extension is required if the receiver is loadeddirectly from a __strong objectwith precise lifetime semantics.
Rationale: implicit autoreleases carry therisk of significantly inflating memory use, so it's important toprovide users a way of avoiding these autoreleases. Tying this toprecise lifetime semantics is ideal, as for local variables thisrequires a very explicit annotation, which allows ARC to trust theuser with good cheer.
A type is a C retainable pointer typeif it is a pointer to (possibly qualified) void or apointer to a (possibly qualifier) struct or classtype.
Rationale: ARC does not manage pointers ofCoreFoundation type (or any of the related families of retainable Cpointers which interoperate with Objective-C for retain/releaseoperation). In fact, ARC does not even know how to distinguish thesetypes from arbitrary C pointer types. The intent of this concept isto filter out some obviously non-object types while leaving a hook forlater tightening if a means of exhaustively marking CF types is madeavailable.
[beginning Apple 4.0, LLVM 3.1]
A C function may be marked with the cf_audited_transferattribute 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 function obeys the create/copy namingconvention if its name contains as a substring:
Createor
Copynot followed by a lowercase letter, or
createor
copynot followed by a lowercaseletter and not preceded by any letter, whether uppercase or lowercase.
A second attribute, cf_unknown_transfer, signifies that afunction's transfer semantics cannot be accurately captured using anyof these annotations. A program is ill-formed if it annotates thesame function with both cf_audited_transferand cf_unknown_transfer.
A pragma is provided to facilitate the mass annotation of interfaces:
#pragma clang arc_cf_code_audited begin ... #pragma clang arc_cf_code_audited end
All C functions declared within the extent of this pragma aretreated as if annotated with the cf_audited_transferattribute unless they otherwise have the cf_unknown_transferattribute. The pragma is accepted in all language modes. A programis ill-formed if it attempts to change files, whether by including afile 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).
Rationale: A significant inconvenience inARC programming is the necessity of interacting with APIs based aroundC retainable pointers. These features are designed to make itrelatively easy for API authors to quickly review and annotate theirinterfaces, in turn improving the fidelity of tools such as the staticanalyzer and ARC. The single-file restriction on the pragma isdesigned to eliminate the risk of accidentally annotating some otherheader's interfaces.
This section describes the interaction between the ARC runtime andthe code generated by the ARC compiler. This is not part of the ARClanguage specification; instead, it is effectively a language-specificABI supplement, akin to the Itanium
generic ABI for C++.
Ownership qualification does not alter the storage requirements forobjects, except that it is undefined behavior if a __weakobject is inadequately aligned for an object of type id. Theother qualifiers may be used on explicitly under-aligned memory.
The runtime tracks __weak objects which holds non-nullvalues. It is undefined behavior to direct modify a __weakobject which is being tracked by the runtime except through anobjc_storeWeak,objc_destroyWeak,or objc_moveWeakcall.
The runtime must provide a number of new entrypoints which thecompiler may emit, which are described in the remainder of thissection.
Rationale: Several of these functions aresemantically equivalent to a message send; we emit calls to Cfunctions instead because:
Several other of these functions are fused
operations whichcan be described entirely in terms of other operations. We use thefused operations primarily as a code-size optimization, although insome cases there is also a real potential for avoiding redundantoperations in the runtime.
Precondition: value is null or a pointer to avalid object.
If value is null, this call has no effect. Otherwise, itadds the object to the innermost autorelease pool exactly as if theobject had been sent the autorelease message.
Always returns value.
Precondition: pool is the result of a previous call toobjc_autoreleasePoolPushon the current thread, where neither pool nor any enclosingpool have previously been popped.
Releases all the objects added to the given autorelease pool andany autorelease pools it encloses, then sets the current autoreleasepool to the pool directly enclosing pool.
Creates a new autorelease pool that is enclosed by the currentpool, makes that the current pool, and returns an opaque handle
to it.
Rationale: while the interface is describedas an explicit hierarchy of pools, the rules allow the implementationto just keep a stack of objects, using the stack depth as the opaquepool handle.
Precondition: value is null or a pointer to avalid object.
If value is null, this call has no effect. Otherwise, itmakes a best effort to hand off ownership of a retain count on theobject to a callto objc_retainAutoreleasedReturnValuefor the same object in an enclosing call frame. If this is notpossible, the object is autoreleased as above.
Always returns value.
Precondition: src is a valid pointer which eithercontains a null pointer or has been registered as a __weakobject. dest is a valid pointer which has not beenregistered as a __weak object.
dest is initialized to be equivalent to src,potentially registering it with the runtime. Equivalent to thefollowing code:
void objc_copyWeak(id *dest, id *src) { objc_release(objc_initWeak(dest, objc_loadWeakRetained(src))); }
Must be atomic with respect to calls to objc_storeWeakon src.
Precondition: object is a valid pointer whicheither contains a null pointer or has been registered asa __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:
void objc_destroyWeak(id *object) { objc_storeWeak(object, nil); }
Does not need to be atomic with respect to callsto objc_storeWeak on object.
Precondition: object is a valid pointer which hasnot been registered as a __weak object. value isnull or a pointer to a valid object.
If value is a null pointer or the object to which itpoints has begun deallocation, object is zero-initialized.Otherwise, object is registered as a __weak objectpointing to value. Equivalent to the following code:
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 callsto objc_storeWeak on object.
Precondition: object is a valid pointer whicheither contains a null pointer or has been registered asa __weak object.
If object is registered as a __weak object, andthe last value stored into object has not yet beendeallocated or begun deallocation, retains and autoreleases that valueand returns it. Otherwise returns null. Equivalent to the followingcode:
id objc_loadWeak(id *object) { return objc_autorelease(objc_loadWeakRetained(object)); }
Must be atomic with respect to calls to objc_storeWeakon object.
Precondition: object is a valid pointer whicheither contains a null pointer or has been registered asa __weak object.
If object is registered as a __weak object, andthe last value stored into object has not yet beendeallocated or begun deallocation, retains that value and returns it.Otherwise returns null.
Must be atomic with respect to calls to objc_storeWeakon object.
Precondition: src is a valid pointer which eithercontains a null pointer or has been registered as a __weakobject. dest is a valid pointer which has not beenregistered as a __weak object.
dest is initialized to be equivalent to src,potentially registering it with the runtime. src may then beleft in its original state, in which case this call is equivalentto objc_copyWeak, or itmay be left as null.
Must be atomic with respect to calls to objc_storeWeakon src.
Precondition: value is null or a pointer to avalid object.
If value is null, this call has no effect. Otherwise, itperforms a release operation exactly as if the object had been sentthe release message.
Precondition: value is null or a pointer to avalid object.
If value is null, this call has no effect. Otherwise, itperforms a retain operation exactly as if the object had been sentthe retain message.
Always returns value.
Precondition: value is null or a pointer to avalid object.
If value is null, this call has no effect. Otherwise, itperforms a retain operation followed by an autorelease operation.Equivalent to the following code:
id objc_retainAutorelease(id value) { return objc_autorelease(objc_retain(value)); }
Always returns value.
Precondition: value is null or a pointer to avalid object.
If value is null, this call has no effect. Otherwise, itperforms a retain operation followed by the operation described inobjc_autoreleaseReturnValue.Equivalent to the following code:
id objc_retainAutoreleaseReturnValue(id value) { return objc_autoreleaseReturnValue(objc_retain(value)); }
Always returns value.
Precondition: value is null or a pointer to avalid object.
If value is null, this call has no effect. Otherwise, itattempts to accept a hand off of a retain count from a call toobjc_autoreleaseReturnValueon value in a recently-called function or something itcalls. If that fails, it performs a retain operation exactlylike objc_retain.
Always returns value.
Precondition: value is null or a pointer to avalid block object.
If value is null, this call has no effect. Otherwise, ifthe block pointed to by value is still on the stack, it iscopied to the heap and the address of the copy is returned. Otherwisea retain operation is performed on the block exactly as if it had beensent the retain message.
Precondition: object is a valid pointer toa __strong object which is adequately aligned for apointer. value is null or a pointer to a valid object.
Performs the complete sequence for assigning to a __strongobject of non-block type. Equivalent to the following code:
id objc_storeStrong(id *object, id value) { value = [value retain]; id oldValue = *object; *object = value; [oldValue release]; return value; }
Always returns value.
Precondition: object is a valid pointer whicheither contains a null pointer or has been registered asa __weak object. value is null or a pointer to avalid object.
If value is a null pointer or the object to which itpoints has begun deallocation, object is assigned nulland unregistered as a __weak object. Otherwise,object is registered as a __weak object or has itsregistration updated to point to value.
Returns the value of object after the call.