OC-堆栈、内存管理

MRC:手动内存管理

ARC:默认是ARC:automatic

Reference Count,自动引用计数器


Person

*p = [[Person alloc] init];

//p就叫做对象的所有者,默认对象出生时,alloc后,对象引用计数器值为1

//当我们看到new alloc创建对象时,引用计数器值为1.

NSLog(@"%lu",p.retainCount);

//retainCount:能够输出对象引用计数器的值



引用计数器的操作

想要管理对象占用的内存,就要学会操作引用计数器。

引用计数器的常见操作:

retain消息:使计数器+1(该方法返回对象本身)

release消息:使计数器-1(不代表释放对象)

retainCount:获得对象当前的应用计数器值,输出:%ld,%lu

注意:release不代表销毁对象,仅仅是引用计数器-1.

怎么判断对象被释放

dealloc方法:只要调用了这个方法,就代表对象即将被释放。

僵尸对象:已经被释放的对象。

野指针:指向僵尸对象的指针。

空指针:指向nil的指针,给空指针发送消息(调用方法)不会报任何错误。

但是,如果没有一个统一的释放原则,name就会造成代码的混乱,会都可以释放,好比一个公司所有的领导没有分工一样,任何事,任何一个领导都可以插一嘴。所以,释放对象要遵循一个原则,那就是谁创建,谁释放。

如果在程序结束后,对象没有被释放,此时称为内存泄漏。

释放对象时,若要查看释放情况,重写dealloc方法:

- (void)dealloc

{

    NSLog(@"%d号房间被释放啦",_fno);

    //这里必须调用父类的dealloc

    [super dealloc];

}


@property参数

格式:@property(参数1,参数2)数据类型 方法名

Setter:改set方法的名字

Getter改get方法的名字

什么是内存管理:(面试必问)

管理堆区内存的分配和释放

分配内存:newalloc copy

释放内存:release



@class


@class Cat;//仅仅告诉编译器Cat是一个猫类,可以声明一个对象。

建议:头文件引入一个类的时候,使用@class。

具体使用:

在.h文件中使用@class引用一个类

在.m文件中使用#import包含这个类的.h文件

引入一个类的方法有两种

#import和@class

区别:

#import方式会包含被引用类的所有信息,包括被引用类的变量和方法;@class方式只是告诉编译器在A.h文件中B

      *b只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中信息。

使用@class方式由于只需要知道被引用类(B类)的名称就可以了,而在实现类由于要用到被引用类中的实体变量和方法,所以需要使#import来包含被引用类的头文件。

通过上面两点也很容易知道在编译效率上,如果有上百个头文件都#import了同一个文件,或者这些文件一次被#import(A->B,B->C,C->D.。。),一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的。而相对来讲,使用@class方式就不会出现这种问题了;

所以我们实际开发中尽量在.h头文件中使用@class

对于循环依赖关系来说,比方A类引用B类,B类也引用A类

这样嵌套包含的代码编译就会报错

当使用@class在两个类相互声明,就不会出现编译器报错

面试题:#import和@class的区别。

作用上的区别

import会包含引用类的所有信息(内容),包括引用类的变量和方法

        @class仅仅是告诉编译器有这么一个类,具体这个类里有什么信息,完全不知道。

效率上的区别

如果有上百个头文件都#import了同一个文件,或者这些文件依次被#import,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,编译效率非常低相对来讲,使用@class方式就不会出现这种问题了。

对于循环retain的情况,对象不能够释放,此时只能让一方使用assign。

@property(nonatomic,assign)Girl      *girl;



NSString


由于字符串是一个特殊的类,因此OC给NSString的retainCount赋值了一个很大的值,因此开发的时候不用考虑NSString的内存管理问题。


自动释放池(ARC)


int main(int argc, const char* argv[]) {

    @autoreleasepool {//自动释放池

        //autorelease:当对象调用这个方法时,就把对象放到了自动释放池中

        Person *p = [[[Person alloc]init]autorelease];

        //不用关注对象什么时候被释放

    }//出了花括号,会对池子里面的所有调用了autorelease方法的对象,做一次release

    return 0;

}


ARC特点总结

不允许调用release,retain,retainCount

允许重写dealloc,但是不允许调用[super dealloc]

@property的参数

strong:相当于原来的retain(适用于OC对象类型),成员变量是强指针

weak:相当于原来的assign(适用于OC对象类型),成员变量是弱指针

assign:适用于非OC对象类型(基础类型)


ARC使用注意事项


ARC中,只要弱指针指向的对象不在了,就直接把弱指针做清空(赋值为nil)操作

_weak Person *p = [[Person alloc]init];//不合理,对象一创建出来就被释放掉,对象释放掉后,ARC把指针设置为nil

ARC在Property处不在使用retain,而是使用strong,在dealloc中不需要在[super

    dealloc],@property(nonatomic,strong)Dog *dog;//意味着生成的成员变量_dog是一个强指针,相当于以前的retain。

如果换成是弱指针,则换成weak,不需要加_.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 内存管理的原理? 内存空间总共有8块区域,有两个区域需要特别注意,一个就是堆空间,一个就是栈空间。栈里存放临时变量...
    Carden阅读 3,349评论 0 1
  • iOS内存管理 概述 什么是内存管理 应用程序内存管理是在程序运行时分配内存(比如创建一个对象,会增加内存占用)与...
    蚊香酱阅读 11,013评论 8 119
  • 29.理解引用计数 Objective-C语言使用引用计数来管理内存,也就是说,每个对象都有个可以递增或递减的计数...
    Code_Ninja阅读 5,531评论 1 3
  • 出门一周,只有睿睿没带作业,说好了回家补做。今天就要兑现了,做一天作业确实是对她来说是很痛苦的事,但是玩就是有代价...
    a晟睿阅读 1,490评论 0 0
  • 早上还是和往常一样,早早起床,送完孩子上学,然后再急匆匆的奔向单位。一切看似平常,但又反常。 因为今天是...
    无边风雨阅读 2,463评论 1 2

友情链接更多精彩内容