ARC Strong/Weak Variables

来源:互联网 发布:空巢青年 知乎 编辑:程序博客网 时间:2024/05/17 08:34

Automatic reference counting (ARC) eliminates all the potential pitfalls associated withmanual reference counting. Under the hood, reference counts are still being maintainedand tracked. However, the system determines when to retain an object and when toautorelease or release it.You don’t have to worry about it at all.

And you don’t have to worry about returning allocated objects from methods.Thecompiler figures out how that object’s memory needs to be managed by generating thecorrect code to autorelease or retain the returned object as necessary.

Strong Variables

By default, all object pointer variables are strong variables.That means that assigning anobject reference to such a variable causes that object to be automatically retained. Further,the old object reference will be released before the assignment is made. Finally, strongvariables are initialized to zero by default.And that’s true whether it’s an instance variableor a local or global variable.

Look at this code, which creates and sets twoFraction objects.Fraction *f1 = [[Fraction alloc] init];

Fraction *f2 = [[Fraction alloc] init];

[f1 setTo: 1 over: 2];[f2 setTo: 2 over: 3];

Now when you write the following using manual memory management

f2 = f1;

the effect is to just copy the reference to theFraction objectf1 intof2.TheFractionobject referenced by f2would be lost as a result, as its value is overwritten.Thiswould create what’s known as a memory leak; a variable that is no longer referenced andtherefore can’t be released.

If you’re using ARC, thenf1 andf2 are both strong variables. So the previous assign-ment actually works like this:

[f1 retain]; // retain new value
[f2 release]; // release the old valuef2 = f1; // copy the reference

Of course, you don’t see this happening because the compiler does all the work foryou.You just the write the assignment statement and forget about it.

Because all object variables are strong variables by default, you don’t need to declarethem as such. However, you can explicitly do so by using the_ _strong keyword for avariable:

_ _strong Fraction *f1;

It’s important to note that properties arenot strong be default.Their default attribute isunsafe_unretained(or, equivalently assign).You’ve seen how to declare thestrongattribute for a property:

@property (strong, nonatomic) NSMutableArray *birdNames;

The compiler makes sure that strong properties survive the event loop by retainingthem on assignment. No such action is taken for properties that areunsafe_unretained(akaassign) or weak.

Weak Variables

Sometimes you set up a relationship between two objects where each object needs to ref-erence the other (this could be as simple as two objects or as complex as a chain ofobjects that create a cycle). For example, iOS applications present graphics on the screenthrough objects known asviews.Views are maintained in a hierarchy. So one view mightpresent an image, and inside that image view you might want to display a title for thatimage.You can set this up where the image view is the main view, and the title is asubview.When the main view is shown, the subview is automatically shown as well.Youcan think of the main image view as the parent view and the title view as the child view.The main image view owns the subview.

When working with this view hierarchy, the parent view certainly will want to hold areference to its subview. But it’s also useful when working with a subview for it to knowwhom its parent view is as well. So the parent view will hold a reference to the subview,and the subview will in turn hold a reference to the parent view.This circular referencecould create problems. For example, what happens when we destroy the parent view? Thereference from the subview to the parent would no longer be valid. In fact, trying to ref-erence that non-existent parent view could cause the application to crash.

When two objects have strong references to each other, you create what’s known as aretain cycle.The system will not destroy an object if there’s still a reference to it. So if twoobjects have strong references to each other, neither can ever be destroyed.

Weak Variables 

The way this problem can be resolved is by creating another type of object variablethat allows a different type of reference, known as aweak reference, to be made betweentwo objects. In this case, the weak reference would be made from the child to the parent.Why? Because we consider an object thatowns another object (in this case the parentview) to be the strong reference, and the other object to be the weak reference.

By making the parent view hold a strong reference to its subview, and the subview aweak reference to its parent view,no retain cycle is created.A weak variable does not pre-vent deallocation of the object it references.

When you declare a weak variable a few things happen; the system tracks the referencethat is made on assignment to that variable.And when that referenced object gets deallo-cated, the weak variable gets automatically set to nil.That prevents any crashes that mightoccur by inadvertently sending a message to that variable. Because the variable will be setnil, sending a message to a nil object does nothing, thus preventing a crash.

To declare a weak variable you use the_ _weak keyword:_ _weak UIView *parentView;

or you use the weak attribute for a property:@property (weak, nonatomic) UIView *parentView;

Weak variables are also useful when working with delegates. By making the variablethat holds the reference to the delegate a weak variable, you’re assured that the variable willbe zeroed if the delegate object gets deallocated. Again, this can prevent the kind of systemcrashes that have caused headaches for many a programmer prior to the invention of ARC.

Note that weak variables are not supported in iOS 4 or Mac OS v10.6. In such cases,you can still use theunsafe_unretained (orassign) property attribute or declare yourvariable to be__unsafe_unretained. However, realize that these variables are notzeroed automatically when the referenced object is deallocated. 


From:<Programming in Objective-C 4th Edition>

原创粉丝点击