summaryrefslogtreecommitdiff
path: root/docs/AutomaticReferenceCounting.rst
diff options
context:
space:
mode:
authorErik Pilkington <erik.pilkington@gmail.com>2019-01-04 18:33:06 +0000
committerErik Pilkington <erik.pilkington@gmail.com>2019-01-04 18:33:06 +0000
commit6d306af57388db45495728891bccdad0156c2c28 (patch)
treefc0ec49f75f6c86991b803f71aa97dd7e0634558 /docs/AutomaticReferenceCounting.rst
parent1188822bbcdd02f816e857f1c15df32d0d8c5336 (diff)
downloadclang-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.rst87
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