底层原理:内存管理

2022-08-05  本文已影响0人  飘摇的水草
定时器

下面这种用法会存在内存泄露

#import "ThirdViewController.h"

@interface ThirdViewController ()
@property (nonatomic, strong) CADisplayLink *link;
@end

@implementation ThirdViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
 
    //__weak typeof(self) weakSelf = self; 加了这句也不管用
    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(linkTest)];
    [link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    self.link = link;
}

- (void)dealloc
{
    [self.link invalidate];
}
@end

NSTimer用下面的方式也会引起内存泄露

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
   
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(linkTest) userInfo:nil repeats:YES];
    self.timer = timer;
}

而使用下面的方式则不会出现内存泄露

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    __weak typeof(self) weakSelf = self;
    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
        [weakSelf linkTest];
    }];
}
内存布局

static变量只有一份,放在数据段区

Tagged Pointer
OC对象的内存管理
extern void _objc_autoreleasePoolPrint(void);

使用时,先在文件上方声明一下:extern void _objc_autoreleasePoolPrint(void);,使用时这样即可:_objc_autoreleasePoolPrint()

MRC中的set方法

在MRC环境下,正确的 set 方法如下:

- (void)setPerson:(Person *)person
{
   if (_person != person)
   {
      [_person release];
      _person = [person retain];
   }
}

在MRC环境下常用的内存管理例子如下:

    //系统方式
    self.array = [NSMutableArray array];
    self.array = [[[NSMutableArray alloc]init] autoRelease];
    
    self.array = [[NSMutableArray alloc]init];
    [self.array release];
    
    NSMutableArray *array = [[NSMutableArray alloc]init];
    self.array = array;
    [array release];

或者用下面的方式给自定义对象创建工厂方法:

@interface Person : NSObject
+ (instancetype)person;
@end

@implementation Person
+ (instancetype)person
{
    return [[[self alloc]init]autoRelease];
}
@end

synthesis 关键字的用法,@synthesize person = _person 这句话表明生成一个 person 的成员变量,来代替 _person 的变量
在 MRC 环境下,需要在子类的 dealloc 方法里调用父类的 dealloc 方法

copy用法

iOS提供了2个拷贝方法

  1. copy,不可变拷贝,产生不可变副本
  2. mutableCopy,可变拷贝,产生可变副本,都是深拷贝
引用计数的存储
weak指针的原理

本质上是将弱引用存放在一个散列表中,即哈希表,对象要销毁时,则从表中取出当前对象对应的弱引用表,把表中存储的那些弱引用清除掉。

autorelease 原理

如果是多层@autoreleasepool的嵌套,会用同一个AutoreleasePoolPage对象,以下面的三个嵌套为例,在同一个page中的顺序是下图这样,不同的@autoreleasepool以POOL_BOUNDARY做分割。

上一篇 下一篇

猜你喜欢

热点阅读