iOS开发经验集

iOS-底层原理(26)-内存管理之内存布局+Tagged Po

2018-09-24  本文已影响60人  路飞_Luck
一 iOS程序的内存布局
image.png

代码例子如下

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);
}

分析结果如下

/*
 字符串常量
 str=0x1029a4068
 
 已初始化的全局变量、静态变量
 &a =0x1029a4db8
 &c =0x1029a4dbc
 
 未初始化的全局变量、静态变量
 &d =0x1029a4e80
 &b =0x1029a4e84
 
 堆
 obj=0x60400001b510
 
 栈
 &f =0x7ffeed25a990
 &e =0x7ffeed25a994
 */
二 Tagged Pointer
三 判断是否为Tagged Pointer
// 如果是iOS平台(指针的最高有效位是1,就是Tagged Pointer)
#   define _OBJC_TAG_MASK (1UL<<63)

// 如果是Mac平台(指针的最低有效位是1,就是Tagged Pointer)
#   define _OBJC_TAG_MASK 1UL

- (BOOL)isTaggedPointer:(id)pointer {
    return ((uintptr_t)pointer & _OBJC_TAG_MASK) == _OBJC_TAG_MASK;
}

调用

// 是否是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);
}

执行结果

image.png

图解说明

image.png
四 MRC
1.MRC环境下Set方法内部实现
@property (nonatomic, assign) int age;

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

- (int)age {
    return _age;
}
@property (nonatomic, retain) Dog *dog;

- (void)setDog:(Dog *)dog {
    if (_dog != dog) {
        [_dog release];
        _dog = [dog retain];
    }
}

- (Dog *)dog {
    return _dog;
}
@property (copy, nonatomic) NSArray *data;

- (void)setData:(NSArray *)data {
    if (_data != data) {
        [_data release];
        _data = [data copy];
    }
}
五 OC对象的内存管理
内存管理的经验总结
// 声明一
NSMutableArray *data = [[NSMutableArray alloc] init];
self.data = data;
[data release];

// 声明二
NSMutableArray *data = [NSMutableArray array];
self.data = data;

两个声明方式相同,只是一个有调用release操作,一个没有。因为array内部会调用autorelease方法。


本文参考MJ底层原理教程,非常感谢


项目连接地址 - MemoryManage-CADisplayLink+Timer

上一篇下一篇

猜你喜欢

热点阅读