3

When you write code like below in ARC

__weak NSMutableArray* array = [[NSMutableArray alloc] init];

The compiler will show you a warning or error and say "Assigning retained object to weak variable. object will be released after assignment".

But if you write like this:

__weak NSMutableArray* array = [NSMutableArray array];

There is no error.

I'm wondering if the second usage is reasonable in some situations? What's the difference between these two codes from memory management perspective? How does it work?

Entreri
  • 55
  • 5

3 Answers3

1

They are the same because you lose the object instantly. Compiler cannot know probably, except alloc init, that the object will be lost.

Yunus Eren Güzel
  • 3,018
  • 11
  • 36
  • 63
  • 1
    Thanks. I'm thinking about complier don't know the [NSMutableArray array] is a object creation. That makes sense to me. – Entreri Mar 07 '16 at 09:24
1

There can be very subtle differences that the compiler cannot know.

Let's take an immutable version: [NSArray array] could return the very same static object every time. So your weak variable will point to a valid object, that has a strong reference somewhere else. Or think of the singleton pattern. On the other hand, when calling alloc/init, convention dictates that you're the only owner of that object, and that will typically leave you with nothing.

Also, the factory method certainly looks more like a (functional) method. In any case, it doesn't communicate ownership of what it returns very well. For an autoreleased object, it's not clear whether you're the the only owner or a shared owner.

Eiko
  • 25,601
  • 15
  • 56
  • 71
0

In the first form, the method returns a retained object. ARC ensures, that the object is released when there is no strong reference on the call-site. This is immediately true, with the weak reference - thus, the compiler emits a warning or error.

In the second form, the method returns an unretained object. In this case, the compiler 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. That is, there is a strong reference created by the compiler. This strong reference will be automatically released by the compiler generated code.

Thus, in this case there's no error or warning.

In the worst case, holding that object may require to use an autorelease pool. However the compiler can apply certain optimisations which avoids this. Thus we should not assume that the returned object lives in an auto release pool.

See specification: http://clang.llvm.org/docs/AutomaticReferenceCounting.html#id14

See also this question on SO: Difference between [NSMutableArray array] vs [[NSMutableArray alloc] init]

Community
  • 1
  • 1
CouchDeveloper
  • 18,174
  • 3
  • 45
  • 67