IOS 5 Programming Memory Management Arc Technology Overview

Source: Internet
Author: User
Tags modifiers

Automatic Reference Counting (ARC) is a compile-time technology that simplifies the memory management of OBJECTIVE-C programming with this technique.

Here I translate this technique into automatic memory counter management technology, which is the difference between OBJECTIVE-C code that uses and does not use this technique.

Arc technology is released with XCode4.2, and in the default project template, you can specify whether your project supports ARC technology, and if you don't specify engineering support for ARC technology, in code you have to manage memory using code that manages memory.

Overview

Automatic counting (ARC) is a technique that works during compilation to help you manage memory, and through it, the program staff can spend less effort on retain, freeing, and so on.

Arc adds the appropriate retain, release, autorelease and other functions for each OBJECTIVE-C pointer variable during compilation, keeping the lifetime control of each variable within reasonable bounds, in order to achieve automatic memory management on the code.

In order for the compiler-generate correct code, ARC imposes some restrictions on the methods you can use, and on how Y ou use toll-free bridging (see "Toll-Free bridged Types"); ARC also introduces new lifetime qualifiers for object references and declared properties.

You can use the compile tag-fobjc-arc来让你的工程支持ARC。ARC在Xcode4.2中引入,在Mac OS X v10.6,v10.7 (64位应用),iOS 4,iOS 5中支持,Xcode4.1中不支持这个技术.

If your current project does not support arc technology, you can convert your project through an automatic conversion tool (tool in Edit->convert menu), which automatically converts the points of the manually managed memory in all projects into the appropriate automated way (such as removing retain, Release, etc.). This tool will convert all the files in the project. Of course you can convert individual files.

ARC provides automatic memory management capabilities

ARC makes it unnecessary for you to think about when to use functions like retain,release,autorelease to manage memory, which provides the ability to automatically evaluate memory lifetimes, and automatically joins the appropriate method of managing memory during compilation. The compiler will also automatically generate the Dealloc function. In general, with ARC technology, you can ignore the traditional way of memory management, but in-depth understanding of traditional memory management is very necessary.

The following is a declaration and implementation of a person class that uses arc technology.

@interface Person:nsobject
@property (nonatomic, strong) NSString *firstname;
@property (nonatomic, strong) NSString *lastname;
@property (nonatomic, strong) NSNumber *yearofbirth;
@property (nonatomic, strong) person *spouse;
@end
@implementation person
@synthesize FirstName, LastName, Yearofbirth, spouse;
@end

(For help with strong, please refer to "ARC introduces New Lifetime Qualifiers.")

With arc, you can implement the contrived function as follows:

-(void) contrived {
    Person *aperson = [[Person alloc] init];
    [Aperson setfirstname:@ "William"];
    [Aperson setlastname:@ "Dudney"];
    [Aperson:setyearofbirth:[[nsnumber alloc] initwithinteger:2011];
    NSLog (@ "Aperson:%@", Aperson);
}

ARC manages memory, so here you don't have to worry about the temporary variables of Aperson and nsnumber causing a memory leak.

You can also implement the Takelastnamefrom in the person class as follows: Method,

-(void) Takelastnamefrom: (person *) person {
    NSString *oldlastname = [self lastName];
    [Self Setlastname:[person lastName]];
    NSLog (@ "Lastname changed from%@ to%@", Oldlastname, [self Lastname]);
}

ARC guarantees that the Oldlastname still exists in memory when NSLog is called.

New rules in Arc

In order for Arc to work smoothly, add the following rules, which may be for more robust memory management, it is possible to better use the experience, it is possible to simplify the writing of code, no matter how, please do not violate the following rules, if violated, you will get a compile-time error.

    • The following functions:,,,, and dealloc, retain release retainCount autorelease。禁止任何形式调用和实现(dealloc可能会被实现),包括使用 @selector(retain) @selector(release) so on, are implicitly called.

      You may implement a dealloc that is not related to memory management, for example, just to invoke [systemClassInstance setDelegate:nil] , but do not call [super dealloc] because the compiler will handle these things automatically.

    • You are not allowed to use NSAllocateObject 或者 NSDeallocateObject .

      使用alloc申请一块内存后,其他的都可以交给运行期的自动管理了。

    • You cannot use a pointer to a class in objective-c in a struct in C.

      Use class classes to manage your data.

    • 不能使用NSAutoreleasePool.

      作为替代,@autoreleasepool被引入,你可以使用这个效率更高的关键词。

    • Memory zones cannot be used.

      NSZone不再需要-This class has been abandoned by modern objective-c.

ARC also has some new rules for the naming of functions and convenience variables.

    • attribute variables that begin with new are forbidden to be named.

ARC introduces New Lifetime Qualifiers

ARC introduces several new lifetime qualifiers for objects, and zeroing weak references. A Weak reference does not extend the lifetime of the object it points to. A zeroing Weak reference automatically becomes nil if the object it points to is deallocated.

You should take advantage of these qualifiers to manage the object graphs in your program. In particular, ARC does not guard against strong reference cycles (previously known as retain Cycles-see "practical Memory Management "). Judicious use of weak relationships would help the ensure you don't create cycles.

Property variable Modifiers

Weak and strong two modifiers are newly introduced, using the following example:

The following functions and: @property (retain) MyClass *myobject;
@property (strong) MyClass *myobject;
The following functions and "@property (assign) MyClass *myobject;" Acquaintance
The difference is that if the MyClass instance is refactored, the value of this attribute variable becomes nil, not a wild pointer,
@property (weak) MyClass *myobject;

Variable Qualifiers

You have the following lifetime qualifiers for variables just as you would, say, const .

__strong
__weak
__unsafe_unretained
__autoreleasing

__strongis the default. __weakspecifies a zeroing weak reference to an object. __unsafe_unretained Specifies weak reference to a object that's not zeroing-if the object it references was deallocated, the pointer is left Dangling. You use the __autoreleasing denote arguments that is passed by reference () and is autoreleased on id * return.

Take care when using __weak variables on the stack. Consider the following example:

NSString __weak *string = [[NSString alloc] initwithformat:@ "first Name:%@", [self firstName]];
NSLog (@ "string:%@", string);

Although string is used after the initial assignment, there are no other strong reference to the string object at the time O f Assignment; It is therefore immediately deallocated. The log statement shows that has string a null value.

You also need to take care with objects passed by reference. The following code would work:

Nserror *error = nil;
BOOL OK = [MyObject performoperationwitherror:&error];
if (! OK) {
    Report the error.
    // ...

However, the error declaration is implicitly:

Nserror * __strong e = nil;

And the method declaration would typically be:

-(BOOL) Performoperationwitherror: (Nserror * __autoreleasing *) error;

The compiler therefore rewrites the code:

 nserror __strong *error = nil; 
 nserror __autoreleasing *tmp = error; 
 BOOL OK = [MyObject performoperationwitherror:&tmp]; 
 error = tmp; 
 if (!
  OK) {
//Report the error. 
//... 

The mismatch between the local variable declaration () and the parameter __strong ( __autoreleasing ) causes the compiler to create the Te Mporary variable. You can get the original pointer by declaring the parameter when you take the id __strong * address of a __strong variable. Alternatively you can declare the variable as __autoreleasing .

Use Lifetime Qualifiers to Avoid strong Reference Cycles

You can use the lifetime qualifiers to avoid strong reference cycles. For example, typically if you had a graph of objects arranged in a Parent-child hierarchy and parents need to refer to th Eir children and vice versa, then your make the parent-to-child relationship strong and the child-to-parent relationship we Ak. Other situations is more subtle, particularly when they involve block objects.

In manual reference counting mode, have the effect of not __block id x; retaining x . In the ARC mode, __block id x; defaults to retaining (just as all other x values). To get the manual reference counting mode behavior under ARC, you could use __unsafe_unretained __block id x; . As the name __unsafe_unretained implies, however, having a non-retained variable are dangerous (because it can dangle) and is therefore D Iscouraged. Better options __weak is to either use (if you don't need to support IOS 4 or OS X v10.6), or set the __block value to c8/> to break the retain cycle.

The following code fragment illustrates this issue using a pattern which is sometimes used in manual reference counting.

Myviewcontroller *mycontroller = [[Myviewcontroller alloc] init ...];
// ...
Mycontroller.completionhandler =  ^ (nsinteger result) {
   [Mycontroller Dismissviewcontrolleranimated:yes Completion:nil];
};
[Self Presentviewcontroller:mycontroller animated:yes completion:^{
   [Mycontroller release];
}];

As described, instead, can use a qualifier and set the variable to in the __block myController nil completion handler:

__block Myviewcontroller *mycontroller = [[Myviewcontroller alloc] init ...];
// ...
Mycontroller.completionhandler =  ^ (nsinteger result) {
    [Mycontroller Dismissviewcontrolleranimated:yes Completion:nil];
    Mycontroller = nil;
};

Alternatively, you can use a temporary __weak variable. The following example illustrates a simple implementation:

Myviewcontroller *mycontroller = [[Myviewcontroller alloc] init ...];
// ...
__weak Myviewcontroller *weakmyviewcontroller = Mycontroller;
Mycontroller.completionhandler =  ^ (nsinteger result) {
    [Weakmyviewcontroller Dismissviewcontrolleranimated:yes Completion:nil];
};

For non-trivial Cycles, however, your should use:

Myviewcontroller *mycontroller = [[Myviewcontroller alloc] init ...];
// ...
__weak Myviewcontroller *weakmycontroller = Mycontroller;
Mycontroller.completionhandler =  ^ (nsinteger result) {
    Myviewcontroller *strongmycontroller = Weakmycontroller;
    if (Strongmycontroller) {
        // ...
        [Strongmycontroller Dismissviewcontrolleranimated:yes Completion:nil];
        // ...
    }
    else {
        Probably nothing ...
    }
};

In some cases you can use __unsafe_unretained if the class isn ' t __weak compatible. This can, however, become impractical for nontrivial cycles because it can is hard or impossible to validate that the pointer is still valid and still points to the same object in question.

Auto Free Pool

With arc, you can't useNSAutoReleasePool类来管理自动释放池了,作为替代,ARC使用一个新的语法结构:

@autoreleasepool {
     Code, such as a loop that creates a large number of temporary objects.
}

Depending on whether the project uses arc, the compiler determines the final presentation of the syntax structure, which uses a NSAutoReleasePool more efficient approach.

Outlets

The patterns for declaring outlets in IOS and OS X, with ARC and become consistent across both platforms. The pattern you should typically adopt is:outlets should weak is, except for those from File's Owner to Top-lev El objects in a nib file (or a storyboard scene) which should is strong .

Outlets that you create should would therefore generally be by weak default:

    • Outlets that you create to, for example, subviews of a view controller ' s view or a window controller ' s window, is Arbitra Ry references between objects that does not imply ownership.

    • strongThe outlets is frequently specified by framework classes (for example, UIViewController ' s view outlet, or NSWindowController ' s window outle T).

For example:

@interface Myfilesownerclass:superclass
@property (weak) Iboutlet MyView *viewcontainersubview;
@property (Strong) Iboutlet Myotherclass *toplevelobject;
@end

In cases where do you cannot create a weak reference to an instance of a particular class (such NSTextView as), you should use rather than weak :

@property (assign) Iboutlet Nstextview *textview;

This pattern extends to references from a container view to their subviews where you have to consider the internal Consistency of your object graph. For example, in the case of a table view cell, outlets to specific subviews should again typically is weak . If A table view contains an image view and a text view, then these remain valid so long as they is subviews of the table View cell itself.

Outlets should is changed to when the strong outlet should is considered to own the referenced object:

    • As indicated previously, this often the case with File ' s owner:top level objects in a nib File is frequently considered To is owned by the File ' s Owner.

    • Some situations need an object from a nib file to exist outside of its original container. For example, might has an outlet for a view, can is temporarily removed from its initial view hierarchy and must therefore be maintained independently.

Other new features

Using arc technology, the pointers allocated on the stack are implicitly initialized to nil, such as

-(void) MyMethod {
    NSString *name;
    NSLog (@ "Name:%@", name);
}

The above code will log out a null and will not cause the program to crash if not using arc technology.

IOS 5 Programming Memory Management Arc Technology Overview

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.