diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2019-01-04 18:33:06 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2019-01-04 18:33:06 +0000 |
commit | 6d306af57388db45495728891bccdad0156c2c28 (patch) | |
tree | fc0ec49f75f6c86991b803f71aa97dd7e0634558 /docs/AutomaticReferenceCounting.rst | |
parent | 1188822bbcdd02f816e857f1c15df32d0d8c5336 (diff) | |
download | clang-6d306af57388db45495728891bccdad0156c2c28.tar.gz |
[ObjCARC] Add an new attribute, objc_externally_retained
This attribute, called "objc_externally_retained", exposes clang's
notion of pseudo-__strong variables in ARC. Pseudo-strong variables
"borrow" their initializer, meaning that they don't retain/release
it, instead assuming that someone else is keeping their value alive.
If a function is annotated with this attribute, implicitly strong
parameters of that function aren't implicitly retained/released in
the function body, and are implicitly const. This is useful to expose
for performance reasons, most functions don't need the extra safety
of the retain/release, so programmers can opt out as needed.
This attribute can also apply to declarations of local variables,
with similar effect.
Differential revision: https://reviews.llvm.org/D55865
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350422 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'docs/AutomaticReferenceCounting.rst')
-rw-r--r-- | docs/AutomaticReferenceCounting.rst | 87 |
1 files changed, 73 insertions, 14 deletions
diff --git a/docs/AutomaticReferenceCounting.rst b/docs/AutomaticReferenceCounting.rst index d8cda0c05f..3e51d2f5d7 100644 --- a/docs/AutomaticReferenceCounting.rst +++ b/docs/AutomaticReferenceCounting.rst @@ -1734,20 +1734,78 @@ A program is ill-formed if it refers to the ``NSAutoreleasePool`` class. 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 Objective-C method is never actually -retained by the implementation. It is undefined behavior, or at least -dangerous, to cause an object to be deallocated during a message send to that -object. - -To make this safe, for Objective-C instance methods ``self`` is implicitly -``const`` unless the method is in the :ref:`init family -<arc.family.semantics.init>`. Further, ``self`` is **always** implicitly -``const`` within a class method. +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 @@ -1758,9 +1816,9 @@ To make this safe, for Objective-C instance methods ``self`` is implicitly without this retain and release. Since it's extremely uncommon to actually do so, even unintentionally, and since there's no natural way for the programmer to remove this retain/release pair otherwise (as there is for - other parameters by, say, making the variable ``__unsafe_unretained``), we - chose to make this optimizing assumption and shift some amount of risk to the - user. + 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: @@ -1769,8 +1827,9 @@ Fast enumeration iteration variables If a variable is declared in the condition of an Objective-C fast enumeration loop, and the variable has no explicit ownership qualifier, then it is -qualified with ``const __strong`` and objects encountered during the -enumeration are not actually retained. +implicitly :ref:`externally-retained <arc.misc.externally_retained>` so that +objects encountered during the enumeration are not actually retained and +released. .. admonition:: Rationale |