Compiler feature ARC

Posted by luuno on Tue, 09 Jul 2019 20:54:07 +0200

ARC (compiler feature)

  • ARC is a new feature added since iOS 5, which completely eliminates the tedious manual management of memory. The compiler will automatically insert appropriate retain, release, autorelease statements in the appropriate place. You don't have to worry about memory management anymore, because the compiler handles everything for you.

  • ARC is a compiler feature, not an iOS runtime feature, nor is it similar to garbage collectors in other languages. So ARC has the same performance as manual memory management, sometimes faster, because compilers can also perform some optimizations.

ARC fundamentals (not java-like garbage collection mechanisms)

The ARC rule is very simple: as long as there is a strong pointer variable pointing to the object, the object will remain in memory

Strong pointer and weak pointer

  • By default, all instance variables and local variables are Strong pointers

  • When the object pointed by the weak pointer is reclaimed, the weak pointer will automatically change to the nil pointer, which will not cause the wild pointer error.

ARC criteria: as long as there is no strong pointer pointing to the object, it will release the object, weak pointer will not do so, timely weak pointer pointing to the object, object does not have strong pointer pointing, it will automatically release. Normally, you don't need to explicitly declare a strong pointer, but in encapsulation, you need to specify when defining a method. Weak pointers, however, must be explicitly stated. The default is a strong pointer.

ARC Characteristics

 1 > Calls to release, retain, retainCount are not allowed

 2 > Rewriting dealloc is allowed, but calls to [super dealloc] are not allowed

 3> @property parameter

  * strong: Membership variables are strong pointers (for OC object types)

  * weak: The member variable is a weak pointer (for OC object types)

  * assign: For non-OC object types

 4 > Change the previous retain to strong

There are two kinds of oc pointers:

 1 > Strong pointers: By default, all pointers are strong pointers _strong

 2 > Weak pointer: _weak

/*File name: Dog.h */#import <Foundation/Foundation.h>@interface Dog : NSObject@end/*File name: Dog.m */#import "Dog.h"@implementation Dog- (void)dealloc
{
    NSLog(@"Dog is dealloc");
}@end/*File name: Person.h */#import <Foundation/Foundation.h>@class Dog;@interface Person : NSObject
@property (nonatomic, strong) Dog *dog;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) int age;@end/*File name: Person.m */#import "Person.h"@implementation Person- (void)dealloc
{
    NSLog(@"Person is dealloc");    // [super dealloc]; can't write, otherwise the error}@end//main.m import <Foundation/Foundation.h> #import #Person.h #import #Dog.h"int main ()
{
    Dog *d = [[Dog alloc] init];
    Person *p = [[Person alloc] init];
    p.dog = d;
    
    d = nil;
    NSLog(@"%@", p.dog);    
    return 0;
}void test()
{    // Wrong Writing (meaningless Writing)
    __weak Person *p = [[Person alloc] init];
    NSLog(@"%@", p);
    NSLog(@"------------");
}

Refactoring old code (manual memory management refactoring to ARC mode) xcode6

After doing so, you can convert non-ARC projects into ARC projects.

How to see if the project is ARC?

Search for auto in build settings to see options:

How to make ARC and non-ARC coexist in one project?

Often we need to use third-party frameworks, or some other old code, then there are ARC support, there are also not support, how to do? It can be set as follows: in the compile option

Double-click the file that requires non-ARC, as follows:

-fno-objc-arc

This allows the file to use keywords such as retain, release, autorelease, etc.

- f stands for the meaning of flags tag, fixed writing.

 

Conversely, for non-ARC projects, set this:

-f-objc-arc

ARC Use Note

  • Can't call release, retain, autorelease, retainCount

  • Dealoc can be overridden, but [super dealloc] cannot be invoked

  • @ property: If you want to have an object for a long time, you should use strong and other objects use weak.

  • Other basic data types still use assign

  • When two ends refer to each other, one end uses strong and the other end uses weak.

Similarly, in the ARC project, there is also the phenomenon of circular double-ended reference, you strong me, I strong your situation. The solution remains the same. When two ends refer to each other, one end uses strong and the other end uses weak.

/*File name: Dog.h */#import <Foundation/Foundation.h>@class Person;@interface Dog : NSObject
@property (nonatomic, weak) Person *person;@end/*File name: Dog.m */#import "Dog.h"@implementation Dog- (void)dealloc
{
    NSLog(@"Dog--dealloc");
}@end/*File name: Person.h */#import <Foundation/Foundation.h>@class Dog;@interface Person : NSObject
@property (nonatomic, strong) Dog *dog;@end/*File name: Person.m */#import "Person.h"@implementation Person- (void)dealloc
{
    NSLog(@"Person--dealloc");
}@end//  main.m#import <Foundation/Foundation.h>#import "Person.h"#import "Dog.h"/*
 When both ends are referenced circularly, the solution is:
 1> ARC
 1 Use strong at the end and weak at the other end.
 
 2> Non ARC
 1 End with retain and end with assign */int main()
{
    Person *p = [[Person alloc] init];
    Dog *d = [[Dog alloc] init];
    p.dog = d;
    d.person = p;    return 0;
}

Otherwise, it's also an error, such as using strong attributes.

 Person *p = [[Person alloc] init];    
    Dog *d = [[Dog alloc] init];

Memory layout:

p.dog = d; // assigns the dog object to the _dog in the person object. The pointer is a strong pointer.

d.person = p; // Similarly, the _person strong pointer in the dog object points to the person object

When the program is executed, or main function is executed, the variable is destroyed automatically.

Because they are all strong pointers, memory leaks occur as above. So _weak or weak attributes are generally used in circular references, but not in other situations.


Topics: iOS Java