Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use NS_RETURNS_INNER_POINTER flag

I do a task to adopt Modern Objective-C an I use Refactoring tool in Xcode: Edit > Refactor > Convert to Modern Objective-C Syntax.

In project I had a method return const void * type. And after refactor tool auto add NS_RETURNS_INNER_POINTER flag after this method. I did check about this flag in FoundationOlderNotes but it's not clear for me.

  1. Is it necessary to add NS_RETURNS_INNER_POINTER for any method or property that return type of non object pointer?
  2. what exactly compiler do with pointer return of method in ARC?
like image 494
larva Avatar asked Jan 20 '15 10:01

larva


1 Answers

NS_RETURNS_INNER_POINTER is a Cocoa-specific equivalent for the objc_returns_inner_pointer method attribute. The docs are here:

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.

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 precise lifetime semantics.

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.

To answer your specific questions:

  1. No, it is not necessary for every method or property which returns a non-object pointer to be annotated with NS_RETURNS_INNER_POINTER. It should only be done if it's returning an "inner" or "interior" pointer. That is, a pointer which will become invalid if the object itself is deallocated.
  2. What exactly the compiler does is not specified. In some implementations, it may simply retain and autorelease the object which returned the inner pointer.
like image 79
Ken Thomases Avatar answered Oct 25 '22 03:10

Ken Thomases