内存管理之为什么不能用assign修饰OC对象

原因:

会造成野指针,相对于weak而言在对象释放后没有自动置为nil。

现在iOS编程采用的ARC(自动管理引用计数),但其本质和MRC(手动管理引用计数)是一样的,只不过是引用计数的管理交给了系统。

使用哪些方法之后需要我们release?

alloc/new/copy/mutableCopy/retain

直接使用类方法创建对象之后为什么不需要release,如创建数组的array方法?

原因:类方法内部对创建的对象进行了一次autorelease操作。

assign修饰OC对象为什么会造成野指针?

@property修饰的属性会为我们自动生成三个东西:
1.带有下划线的成员变量
2.set方法
3.get方法
我们需要看看使用了assign之后生成的set方法

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

我们通常会用assign修饰基本数据类型,基本数据类型的分配在栈上,由系统进行分配和释放,所以不会出现野指针,而如果我们用assign去修饰OC对象,看生成的set方法

- (void)setDog:(Dog *)dog
{
    _dog = dog;
}

Dog是一个继承自NSObject的类,生成这样的set方法后会有什么问题呢?
我们假设Dog还有一个eat方法,看Dog.m文件中的代码:

@implementation Dog

- (void)eat{
NSLog(@"狗吃东西...");
}

-(void)dealloc{
NSLog(@"狗被释放了...");

[super dealloc];
}

@end

我们去使用一下Person中的Dog,代码:

Person * p = [[Person alloc] init];
Dog * d = [[Dog alloc] init];

[p setDog:d];

[d release];

[[p dog] eat];
[p release];

当我们打开"Zombie Objects"(僵尸对象)会发现上面的代码报错

-[Dog eat]: message sent to deallocated instance 0x10070b380

提示我们向一个已经被销毁了的对象发送了一个eat消息。这就是野指针问题,当我们外部的Dog对象释放之后,Person持有Dog对象也被销毁了,然而Dog对象被销毁之后并没有自动置为nil,从而导致了报错。如果Dog对象被销毁之后自动置为nil就会不会报错,因为在OC中给一个nil发消息就直接return了,而不会报错。
这就解释了为什么不能assign修饰OC对象。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,148评论 1 32
  • 内存管理的原理? 内存空间总共有8块区域,有两个区域需要特别注意,一个就是堆空间,一个就是栈空间。栈里存放临时变量...
    Carden阅读 481评论 0 1
  • 内存管理的基本范围和概念. 程序运行过程中药创建大量的对象, 和其他高级语言类似,在ObjC中对象存储在堆区,程序...
    ValienZh阅读 914评论 0 2
  • Oc基础 1、#import的用途 1>#import与#include一样,拷贝文件的内容 2>可以自动防止文件...
    开着保时捷堵你家门口阅读 918评论 0 0
  • 基于爬虫的app快速开发与思考 2016-05-26 从“按空格”公众号 迁移至此 本文适用于有一定android...
    ammike阅读 1,562评论 1 0