Objective-C内存管理

看了视频、文章后总结一下自己理解的Objective-C的内存管理。

ARC

  1. 手动内存管理的基本操作函数及原则(黄金法则或配对原则)
    内存的开辟和销毁时成对出现的。
    在一个代码快中出现了alloc,new,retain,copy,mutabcopy等关键词,当对象不再使用后,就要有对应的release,autorelease 出现与之相对应。
    当对象的“引用计数”(retainCount)变为“0”时对象执行dealloc函数,执行销毁操作。

  2. 当一个类中实例化一个对象时我们可以简单的使用alloc 和 release 解决配对问题。

   Person *p = [[Person alloc] init];
 
   [p run];
 
   [p release]; 
  1. 当一个类最为另一个类的属性时(被另一个类持有)应该怎样配对呢?

    对象 alloc;

  被持有;--------------> 被持有就是执行set方法:所以在set方法中应该retain 对象,在dealloc函数中release对象。

  对象 release;

ps. 以上时两对 内存操作。

  1. 当有两个对象交替被另一个对象持有时改怎样操作呢?

    由于交替操作会使第一个被持有的对象造成内存泄露。

    所以在第一个被持有的对象在本类中不在使用后立刻release,即在set方法中release 第一个被持有的对象。

    代码:

```Objective-C
  - (void)setCar:(Car *)car

  {

      [_car release];

      _car = [car retain];

  }

``` 

  1. 当同一个对象多次被另一个对象持有时会造成第一个对象被过早释放。(僵尸对象,野指针的出现)(野指针的处理方法是给野指针赋值nil,p = nil)

上面的set方法就会出错。

因此我们需要判断两次持有的对象是不是同一个对象。

代码如下:

- (void)setCar:(Car *)car
{
    if(_car != car)
    {    
      [_car release];
      _car = [car retain];
    } 
}

最后的dealloc也需要重写:

- (void)dealloc

{

  [_car release];

  [super release];//最后调用,因为父类执行release后会将子类销毁,下面的代码就不会执行了,造成内存泄露。子类的真正销毁是在父类中执行的。

          //ARC中,可以重写dealloc函数,但是不能写[super release];

}
  1. @property的使用

@property 时为简化get,set方法设计的。我们完全可以用展开的get,set 方法代替。

相关参数:
属性关键字 使用范围 释义 是否是默认值 小贴士
assign 赋值方式 不复制不保留,直接赋值 YES

基本数据类型和本类不直接拥有的对象
retain 赋值方式 将新值保留一份赋覆盖原值 NO 大部分对象可使用
copy 赋值方式 将新值复制一份赋覆盖原值 NO 字符串选择性使用
readwrite 读写权限 生成getter和setter两个方法 YES 变量可读取可修改
readonly 读写权限 只生成getter方法 NO 变量只读不可修改
atomic 原子性 原子操作 YES 可以保留在多线程环境下,能安全的存取值
nonatomic 原子性 非原子操作 NO 不生成多线程同步内容
getter 存取方法 自定义取方法 NO
setter 存取方法 自定义赋值方法 NO

NSString 需要使用copy

@property(nonatomic,copy) NSString *str;

代理中的写法:

@property(nonatomic,assign)id delegate; 因为被代理对象并不是真的持有代理对象,所以为了避免对象的循环引用此处必须使用assign!!

@property(nonatomic,weak) __weak id delegate; ARC中写法。

block中的写法:

@property(nonatomic,retain)int (^changeColor)(int a,int b); MRC

@property(nonatomic,strong)int (^changeColor)(int a,int b); ARC,好像没有什么特殊的%>_<%。。

  1. autorelease

autorelease 主要用于类方法的书写中。

(1)ios 5.0以前的创建方式

NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];

`````````````````

[pool release];//[pool drain];用于mac

(2)Ios5.0以后,且ARC中只能使用这种方式!!!!

@autoreleasepool

{//开始代表创建自动释放池

·······

}//结束代表销毁自动释放池

  1. 循环引用

解决方法:

  1. 在头文件中用@class 声明类。在m文件中引用文件。

2.两端循环引用的解决方法

一端使用retain,一端使用assign(使用assign的在dealloc中也不用再release)

ARC:

ARC新增两个武功高强的左右护法:strong 和 weak (strong 是在arc中是默认值)

strong的含义和retain相同,weak和assign相同,修饰完的属性变量用法也是完全没有改变,不过strong和weak只能修饰对象。

苹果官方对于ARC机制中对象的内存引用规则:

(1)任何对象,如果仍有持有者,就不会销毁

(2)任何对象,已经没有任何持有者,即自动销毁

持有者就是指向对象的指针,如果是strong修饰的,即是对象的持有者,如果是weak属性的,则不是持有者

UI控件、代理都使用weak 防止对象间的循环引用

block 在使用外部对象时要使用间接变量。间接变量使用weak(ios5+)__unsafe__un。

彩蛋:让程序兼容ARC和非ARC部分。转变为非ARC -fno-objc-arc 转变为ARC的, -f-objc-arc

@property修饰符

strong:等同于“retain”,属性成为对象的拥有者,引用计数+1

weak:属性是weak pointer,当对象释放时会自动设置为nil,记住Outlet应该适用weak,引用计数不变

unsafe_unretained:等同于之前的“assign”,只有IOS 4才应该适用

copy:和之前的copy一样,复制一个对象并创建strong关联

assign:对象不能使用assign,但原始类型(BOOL、int、float)任然可以使用

1、非ARC
copy只用于NSString和block
retain用在除NSString、block以外的OC对象
assign用在基本数据类型和枚举、结构体这些非OC对象
当2个对象相互引用,一端用retain,一端用assign。

2、ARC
copy只用于 NSString和block
strong用在除NSString 和block外的OC对象
weak:当2个对象相互引用,一端用strong,一端用weak
assign用在基本数据类型,枚举,结构体这些非OC对象

转载于:https://www.cnblogs.com/vtsay/p/4651882.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值