非ARC开发的内存管理

xiaoxiao2021-02-28  109

一. 内存管理原则

retain和release配对使用;

只要出现retain、alloc、copy中的其中一个,就要用一次release;

只要retainCount为0,系统会自动调用dealloc

@property中使用的关键字

readwrite:属性会被当成读写的,默认 readonly:属性只可读不可写 assign:不会使引用计数加1,常用于数值 retain:会使引用计数加1,只在非ARC中使用 copy:建立一个索引计数为1的对象,在赋值时使用传入值的一份拷贝 nonatomic:非原子性访问,多线程并发访问会提高性能 atomic:原子性访问 strong:打开ARC时才会使用,相当于retain。 weak:打开ARC时才会使用,相当于assign,可以把对应的指针变量置为nil。

二. 属性中没有类类型的属性的内存管理

只要遵循“创建一个对象时,必须有一次release”即可。如下面代码 ---------- 如下,Dog类中属性的类型只有int,没有类类型的属性 #import <Foundation/Foundation.h> @interface Dog : NSObject @property (nonatomic, assign) int age; @end @implementation Dog - (void)dealloc { NSLog(@"%s", __func__); [super dealloc]; } @end ---------- 下面是关于Dog对象的内存管理 // 方式一 Dog *dog1 = [[[Dog alloc] init] autorelease]; // 使用dog // 使用dog代码.... // 方式二 Dog *dog2 = [[Dog alloc] init]; // 使用dog // 使用dog代码.... // 使用完后release [dog2 release];

提示: NSArray *arr = [NSArray array]; 和 NSArray *arr = @[]; 等价,内部已经有了一个autorelease,不需要重复写release

三. 属性中有类类型的属性的内存管理

根据谁使用谁撤销的原则,在dealloc方法中必须设置类类型的属性为空,即给类类型的属性来一次release

如下代码

A. 下面是不使用@property (nonatomic, retain) 的情况

---------- 关于Dog的类如上代码,这里只写Person类,下面是不使用@property (nonatomic, retain) 的情况 #import <Foundation/Foundation.h> #import "Dog.h" @interface Person : NSObject { Dog *_dog; } - (void)setDog:(Dog *)dog; - (Dog *)dog; @end @implementation Person - (void)dealloc { // 必须设置为nil,相当于对self.dog一次release // 保证Person对象不在的时候,dog的引用计数减一,因为是Person引用了一次 self.dog = nil; [super dealloc]; } - (void)setDog:(Dog *)dog { if (_dog != dog) { [_dog release]; _dog = [dog retain]; } } - (Dog *)dog { return _dog; } @end ---------- 关于使用Person类的内存管理 Person *person = [[[Person alloc] init] autorelease]; Dog *dog = [[[Dog alloc] init] autorelease]; person.dog = dog; person.dog = dog;// 即使有第二次赋值,引用计数器也不会加一 NSLog(@"person---%ld", person.retainCount); NSLog(@"person.dog----%ld", person.dog.retainCount);

运行结果:



B. 下面是使用@property (nonatomic, retain) 的情况 这样的好处是不用手动去写类类型的属性的setter方法 上面的Person类可以改成

#import <Foundation/Foundation.h> #import "Dog.h" @interface Person : NSObject @property (nonatomic, retain) Dog *dog; @end @implementation Person - (void)dealloc { // 必须设置为nil,相当于对self.dog一次release // 保证Person对象不在的时候,dog的引用计数减一,因为是Person引用了一次 self.dog = nil; [super dealloc]; } @end

修改后的运行结果一样:


四. copy属性的作用

copy属性是完全把对象重新拷贝了一份,计数器从新设置为1,和之前拷贝的数据完全脱离关系

和retain一样,如果不使用@property (nonatomic, copy) 就必须自己写下面的代码

@property (nonatomic, copy) NSString *string;   - (NSString *) string {   return _string; } - (void)setString:(NSString *)newStr { if (_string != newStr) { [_string release]; _string = [newStr copy]; }
转载请注明原文地址: https://www.6miu.com/read-52297.html

最新回复(0)