A, iOS program memory layout

  • Code snippet: compiled code

  • Data segment

    • String constants: NSString * STR = @”123″
    • Initialized data: initialized global variables, static variables, etc
    • Uninitialized data: uninitialized global variables, static variables, etc
  • Stack: Function call overhead, such as local variables. The allocated memory space address becomes smaller and smaller

  • Heap: Dynamically allocated space via alloc, malloc, calloc, etc. The allocated memory space addresses are getting larger and larger

Here is an example code

int a = 10;
int b;

implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self test1];
}

- (void)test1 {
    static int c = 20;
    
    static int d;
    
    int e;
    int f = 20;
    
    NSString *str = @"123";
    
    NSObject *obj = [[NSObject alloc] init];

    NSLog(@"\n&a=%p\n&b=%p\n&c=%p\n&d=%p\n&e=%p\n&f=%p\nstr=%p\nobj=%p\n",
          &a, &b, &c, &d, &e, &f, str, obj);
}
Copy the code

The analysis results are as follows

/* String constant STR = 0x1029A4068 Initialized global variable, static variable &a = 0x1029A4DB8&c = 0x1029A4DBC Uninitialized global variable, static variable &d = 0x1029A4E80&b = 0x1029A4E84 heap Obj = 0x60400001B510 stack &f = 0x7FFEED25a990&e = 0x7FFEED25A994 */Copy the code

Second, the Tagged Pointer

  • Starting from 64-bit, iOS introduces Tagged Pointer technology to optimize storage of small objects such as NSNumber, NSDate, and NSString

  • Before Tagged Pointer is used, objects such as NSNumber need to dynamically allocate memory and maintain reference counting. The NSNumber Pointer stores the address value of the NSNumber object in the heap

  • After using Tagged Pointer, the Data stored in the NSNumber Pointer becomes Tag + Data, that is, the Data is stored directly in the Pointer

  • When Pointers are insufficient to store data, dynamically allocated memory is used to store data

  • Objc_msgSend can recognize Tagged Pointer, such as the intValue method of NSNumber, and directly extract data from Pointer, saving previous call overhead

  • How do I check whether a Pointer is Tagged Pointer?

    • iOSPlatform, most significant bit is 1 (64bit)
    • MacPlatform, least significant bit is 1

3. Check whether it is Tagged Pointer

# define _OBJC_TAG_MASK (1UL<<63) # define _OBJC_TAG_MASK (1UL<<63) # define _OBJC_TAG_MASK 1UL - (BOOL)isTaggedPointer:(id) {return ((uintptr_t) Pointer & _OBJC_TAG_MASK) == _OBJC_TAG_MASK; }Copy the code

call

// Tagger pointer - (void)test3 {NSNumber *number1 = @4; NSNumber *number2 = @5; NSNumber *number3 = @(0xFFFFFFFFFFFFFFF); NSLog(@"%d %d %d", [self isTaggedPointer:number1], [self isTaggedPointer:number2], [self isTaggedPointer:number3]); NSLog(@"%p %p %p", number1, number2, number3); }Copy the code

The execution result

The illustration shows

Fourth, the MRC

1. Internal implementation of Set method in MRC environment

  • beassignmodified
@property (nonatomic, assign) int age;

- (void)setAge:(int)age {
    _age = age;
}

- (int)age {
    return _age;
}
Copy the code
  • beretainmodified
@property (nonatomic, retain) Dog *dog; - (void)setDog:(Dog *)dog { if (_dog ! = dog) { [_dog release]; _dog = [dog retain]; } } - (Dog *)dog { return _dog; }Copy the code
  • becopymodified
@property (copy, nonatomic) NSArray *data;

- (void)setData:(NSArray *)data {
    if (_data != data) {
        [_data release];
        _data = [data copy];
    }
}
Copy the code

5. OC object memory management

  • In iOS, reference counting is used to manage the memory of OC objects
  • The default reference count of a newly created OC object is 1. When the reference count is reduced to 0, the OC object is destroyed, freeing up its memory
  • A call to retain gives the OC object’s reference count +1, and a call to release gives the OC object’s reference count -1

Summary of experience in memory management

  • When the alloc, new, copy, and mutableCopy methods return an object, release or autoRelease is called when the object is no longer needed
  • To own an object, make its reference count +1; If you don’t want to own an object, let its reference count be -1
  • You can view automatic pool release using the following private functions

    pextern void _objc_autoreleasePoolPrint(void);
NSMutableArray *data = [[NSMutableArray alloc] init]; self.data = data; [data release]; NSMutableArray *data = [NSMutableArray array]; self.data = data;Copy the code

The two declarations are the same, except one calls release and one doesn’t. Because the autoRelease method is called inside the array.


The original address