Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
714 views
in Technique[技术] by (71.8m points)

objective c - Lifetime of weak local variables with ARC

If I have a piece of code that looks like this:

- (void)testSomething
{
  __weak NSString *str = [[NSString alloc] initWithFormat:@"%@", [NSDate date]];
  NSLog(@"%@", str);
}

the output will be (null) because there are no strong references to str and it will be immediately released after I allocate it. This makes sense and is spelled out in the Transitioning to ARC guide.

If my code looks like this:

- (void)testSomething
{
  __weak NSString *str = [NSString stringWithFormat:@"%@", [NSDate date]];
  NSLog(@"%@", str);
}

then it correctly prints out the current date. Obviously you would expect it to work in a non-ARC world, since str would be autoreleased and therefore valid until this method exits. However, in ARC-enabled code people generally consider the two forms (stringWithFormat & alloc/initWithFormat) to be equivalent.

So my question is whether code like the second example is guaranteed to work under ARC. That is, if I have a weak reference to an object that I get via what we would normally consider an autoreleasing convenience constructor, is it guaranteed to be safe to use that reference in the same scope I normally would have without ARC (i.e. until the method exits)?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The conventions of autoreleasing and allocing still apply in the world of ARC. The only difference is that ARC will insert extra retain/release calls to make it much harder to leak objects or access a dealloced object.

In this code:

__weak NSString *str = [[NSString alloc] initWithFormat:@"%@", [NSDate date]];

The only place the object is retained (or equivalent) is the alloc. ARC will automatically insert a release command, causing it to be immediately dealloced.

Meanwhile, in this code:

 __weak NSString *str = [NSString stringWithFormat:@"%@", [NSDate date]];

By convention, the return value of a convenience constructor like this must be an autoreleased object*. That means the current autoreleasepool has retained the object and will not release it until the pool is drained. You are therefore all but guaranteed that this object will exist for at least the duration of your method - although you probably shouldn't rely on this behaviour.

(* or retained in some other way)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...