Objective C ARC Use and principle

Source: Internet
Author: User

Teach you arc, which introduces some of the features of Arc, and the method of converting non-ARC engineering into ARC Engineering

Official ARC Apple Document

Let me introduce the arc in my own words and write down the questions and answers in the documentation process. Some of the following are translations, but not all, be sure to read the official documents again

    • ARC rules without regard to iOS4
Simply put, Arc adds retain and release to the code at the appropriate location at compile time. Complex point, it also provides some other functions, but also to solve some problems, added some keywords and features, later said. New rules for ARC enforcement requirements
    • Can not call Dealloc, can not implement or call retain, release, Retaincount, Autorelease.
    • Can not use Nsallocateobject, Nsdeallocateobject
    • Objective C objects cannot be used in a C struct, for example, the following are not allowed:

        struct A {      NSString *string;  };
    • There is no natural conversion between ID and void *

      ID refers to the Objective C object
      void * refers to the C pointer, cgcolorref this kind of thing
      Assign a value between ID and void * To add the __bridge series keyword (said later)

    • You can not use NSAutoreleasePool to replace @autoreleasepool

    • Memory zones (Nszone) may not be used. (indicates that it has not been used seriously)
    • You cannot give a property a name that starts with new unless you give it a getter that does not start with new. (Cause unknown)

        // Won‘t work  @property NSString *newTitle;  // words:  @property (getter=theNewTitle) NSString *newTitle;
Attribute declarations introduced weak, strong, unsafe_unretained, removed retain, preserved assign remaining unchanged
    • Strong equivalent to MRC (Manual Reference counting) retain
    • The weak is equivalent to the MRC assign but when the pointing object is destroyed, the pointer is set to 0
    • Assign property if it is a objective C object, in the absence of special processing, the equivalent of strong

      The following code is weakly referenced in the MRC case

        @interface MyClass : Superclass {      id thing; // Weak reference.  }  // ...  @end  @implementation MyClass  - (id)thing {      return thing;  }             - (void)setThing:(id)newThing {      thing = newThing;  }  // ...  @end

      But in the ARC case is not the ID thing; was converted into an ID __strong thing;
      So to put the above code ID thing; Change to ID __weak thing; Only to get close to the original assign meaning.

    • Unsafe_unretained and the original assign act most like.

    • For manual write setter getter and set the modifier, I did not study
I think of a lot of questions here.
    1. Declares the attribute @property (weak) nsstring *member Corresponding member variable nsstring *_member (no write __weak in member variable)

       答案是编译出错
    2. Property @property (weak) NSString *member and member variables NSString *_member123 (no write __weak in member variables) What happens @synthesize together?

       答案是写着的时候xcode就显示出了错误
    3. The remaining questions can be deduced from the above two questions and answers.

Variable modifiers

The following variable represents the objective C object variable

    • __strong

      Default, variable in, object in

    • __weak

      Object in, variable can safely use object, object destroyed, variable is set to nil

    • __unsafe_unretained

      Objects are not related to variables, variables are not related to the object, if the object is destroyed, but also by the variable to use the object, it will crash, is not safe. (tacit)

    • The
    • __autorelease

      Indicates that the object being pointed to is autorelease, as an example of

        in Non-arc programming, the Save function looks  Like this:-(BOOL) Save: (Nserror * __autoreleasing *) myerror {*myerror = [[[Nserror alloc] initwith ...] } in ARC programming, the Save function looks like this:-(BOOL) Save: (Nserror * __autoreleasing *) Myerror {*myer  Ror = [[Nserror alloc] initwith ...];   

      Arc code

        nserror *error; BOOL OK = [MyObject performoperationwitherror:&error];  

      is converted to

        nserror * __strong error;  Nserror * __autoreleasing tmp = error;  BOOL OK = [MyObject performoperationwitherror:&tmp]; Error = tmp;  
      The

      can actually use Nserror * __autoreleasing error directly to increase efficiency.

ARC automatically generates additional code based on those modifiers above.

For __strong

NSNumber * __strong number = [NSNumber numberWithInt:13];

will be compiled into

NSNumber * number = [[NSNumber numberWithInt:13] retain];……// 在 number 所在的定义域外, 或者 number = nil 的时候。[number release];

__weak back.

__unsafe_unretained should be doing nothing (guessing)

For __autorelease

NSNumber * __autorelease number = [[NSNumber alloc] initWithInt:13];

will be compiled into

NSNumber * number = [[[NSNumber alloc] initWithInt:13] autorelease];
Modifier can also tell the behavior of the compiler code

For example

NSError * __autoreleasing tmp = error;BOOL OK = [myObject performOperationWithError:&tmp];

MyObject's performoperationwitherror may be using the MRC code, or the ARC code, but the parameter returned is definitely a Autorelease object. With the __autoreleasing modifier, the compiler knows the memory issue that does not need to be processed when TMP is obtained from the Performoperationwitherror method.

The realization of __weak

The __weak pointer is set to nil when the object is destroyed, which is very good and powerful, avoids a lot of problems, but does not appear to be inserting a [obj release] somewhere; obj = nil; can be achieved.

Specifically implemented in how does the ARC ' s zeroing weak pointer behavior implemented? have said.

Here is a brief introduction:

ARC 的 NSObject 里大概添加了一个 weak 指针的数组,当对象销毁的时候,把数组里的变量都设置为 nil (表述不严谨,大概就是这个意思)
Prevent circular references and be destroyed during long periods (the following may be misleading, look critically!) )

__block id x = y in MRC; Block will not [x retain]; will not [x release] after the block is executed;

__block id x = y in ARC; should be equal to __strong __block id x = y; This will have a retain process, [x release] when the block is destroyed.

From the above can be known using __block id x = y; If X has copy of block, no processing will cause a circular reference.

So Apple tells us to write this:

MyViewController * __block myController = [[MyViewController alloc] init…];// ...myController.completionHandler =  ^(NSInteger result) {    [myController dismissViewControllerAnimated:YES completion:nil];    myController = nil;};

But for multiple invocations, the above cannot be achieved. You can use the weak keyword instead of block (note the substitution, not the combination, I'm not working together)

MyViewController *myController = [[MyViewController alloc] init…];// ...MyViewController * __weak weakMyViewController = myController;    myController.completionHandler =  ^(NSInteger result) {    [weakMyViewController dismissViewControllerAnimated:YES completion:nil];};

It can still cause problems, and if the block's code executes for a long time and Weakmyviewcontroller is destroyed during that time, it becomes nil. The program either crashes or gets the wrong result, so it doesn't work, and Apple offers a workaround

MyViewController *myController = [[MyViewController alloc] init…];// ...MyViewController * __weak weakMyController = myController;myController.completionHandler =  ^(NSInteger result) {    MyViewController *strongMyController = weakMyController;    if (strongMyController) {        // ...        [strongMyController dismissViewControllerAnimated:YES completion:nil];        // ...    }    else {        // Probably nothing...    }};

To this surface problem is basically solved.

An eccentric act.

The code is as follows:

@interface AA : NSObject@property (strong) NSString *string;@end@implementation AA- (void)dealloc {    NSLog(@"%@ dealloc", self.string);}@end- (void)testArcSimple {    AA * __strong aa_weak_holder = [[AA alloc] init];    AA * __weak aa_weak = aa_weak_holder;    aa_weak_holder.string = @"aa_weak";    void (^aBlock)(void) = ^(){        NSLog(@"block : %@", aa_weak.string);    };    aa_weak_holder = nil;    aBlock();}

The above output is

block : aa_weakaa_weak dealloc // 这个log出现在一个runloop的最后

And the following code:

AA * __strong aa_weak_holder = [[AA alloc] init];aa_weak_holder.string = @"weak";AA * __weak aa_weak = aa_weak_holder;aa_weak_holder = nil;NSLog(@"aa : %@", aa_weak);

Output to

weak deallocaa : (null)

Guess is aa_weak in

    void (^aBlock)(void) = ^(){        NSLog(@"block : %@", aa_weak.string);    };

position [[Aa_weak retain] autorelease] again. Do not understand.

Toll-Free bridging
    • The conversion between __bridge:objective-c and the Core Foundation has the same ownership.
    • __bridge_retained: Conversion from objective-c to Core Foundation, the programmer is responsible for destroying the resulting cfxxxref
    • __bridge_transfer: Conversion from Core Foundation to Objective-c, the arc is responsible for destroying the obtained ID

__bridge_retained's role equals Cfbridgingretain.
__bridge_transfer's role equals Cfbridgingrelease.

The CF object returned by the Cocoa method

For example [[Uicolor Greencolor] cgcolor]; The compiler knows if the returned cfxxxref need to be release, and when it is necessary to convert it to a Cocoa object, you do not have to use __bridge __bridge_transfer such modifiers, but you need to explicitly write the type you want to convert, such as:

Uicolor *color = (ID) [Uicolor greencolor]. Cgcolor; Although this is more boring.

****************

From Mr. Yang's share ...

****************

Objective C ARC Use and principle

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.