oc基础知识

                           重点知识(内存管理)

管理范围:任何继承了NSObject的对象。


 预备知识内存分配 :栈区,堆区,全局区,文字常量区
        一个由C编译的程序占用的内存分为以下几个部分 
  1、栈区(stack) 由编译器自动分配释放,存放函数的参数值,局部变量的值等

。其操作方式类似于数据结构中的栈。 
  2、堆区(heap) 一般由程序员分配释放若程序员不释放,程序结束时可能由系统

回收。
     注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。 
  3、全局区(静态区)(static),全局变量和静态变量的存储是放在一块的,初

始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量

在相邻的另一块区域。程序结束后由系统释放。 
  4、文字常量区 常量字符串就是放在这里的。程序结束后由系统释放 
  5、程序代码区 存放函数体的二进制代码。
栈:放一些局部变量。指针式局部变量放在栈里。栈里面的东西自动回收。
堆:放动态产生的变量。 对象的内存放在堆里面。堆里面的东西不能自动回收。
堆里面的东西是程序员手动释放的。
  oc里尽管没有任何指针指向对象了,但是只要他在堆空间里,就不会回收。

怎样回收:
      只有给对象发送一条消息,他就回收了。

什么是发送消息:
      就是调用方法,调用对象的某个方法,才能销毁。

怎么判断需不需要回收:
      每个oc对象都有自己的引用计数器,是一个整数,占用4个字节的存储空间。表示对

象引用的次数,当引用引用计数器为0时,把对象回收。

引用计数器的作用:
1,当使用alloc,new,copy创建对象时,新对象的引用计数器默认值是1.
2,当一个对象的引用计数器值为0时,对象占用的内存就会被系统收回。
3,如果对象的引用计数器值不为0,那么在整个程序运行过程,他占用的内存就不可

能被收回,除非整个程序已经退出。

引用计数器的操作:
1,给对象发送一条retain消息,可以使计数器值+1.
2,给对象发送一条release消息,可以使引用计数器值-1.
3,可以给对象发送retainCount消息获得当前的引用计数器值.

对象被回收的两种情况:
1,程序员通过代码在运行过程中就把对象干掉。
2,当程序员退出时,整个程序占用存储空间会自动回收。

怎么验证对象有没有人用:
1,重写对象的dealloc方法,在dealloc括号里打印,有打印说明dealloc有调用,

对象被回收。
调用的dealloc方法,一定要调用super的方法[super dealloc];一定要放到最后面

。当一个对象被回收是,系统会自动调用[super dealloc]方法。计数器值为0时,

系统会自动调用[super dealloc]方法。

对象的销毁:
1,当一个对象的引进计数器值为0时,那么他将销毁。其占用的内存被系统回收。
2,当一个对象被销毁时,系统会自动向对象发送一条dealloc消息。
3,一个般会重写dealloc的方法,在这里释放相关资源,dealloc就像对象的遗言。
4,一旦重写了dealloc方法,就必须用[super dealloc],并放在最后调用。
5,不要直接调用dealloc方法。
6,一旦对象被回收了,他占用的内存就不可用,坚持使用会导致崩溃.(野指针错误

野指针:指向了僵尸对象(不可用内存)的指针。
僵尸对象:所占用内存已经被回收的对象。
空指针:没有指向任何对象的指针。
oc里面给空指针发送消息,不报错。
给野指针发送消息,报错。在程序运行过程中报错,直接闪退。

什么是野指针错误:
      指向了僵尸对象,或者不空用内存的指针。
 
EXC BAD ACCEESS  -> message sent to dealloc cated instance.访问了一块不

能访问的内存空间。(野指针错误)。

Xcod 打开监测僵尸对象程序: Edit streme ->Diagnastics ->oc ->Enable

Zombieobject.

retain是有返回值的,返回值是(id),任何的oc对象。
注意:retain方法返回的是对象本身(他自己)。谁调用retain就返回谁。

set方法的内存管理:利用@property参数
1,@property(retain)Book*book
    return : 生成set方法,release旧值,retain新值
2.@ property(readwrite)  可读可写。
  @property(readonly)只读

修改getter和setter方法的名称:
@property(getter = abc)int weight; 修改getter成员变量的名称。
@property(getter = abc ,setter = setAbc:)int weight; set方法后一定要有

冒号。
setter方法:决定了方法名后一定要有冒号。
getter方法:决定了方法的名称。
getter方法一般用在BOOL类型。

提高性能(多线程管理):
1,nonatomic 性能高
2,atomic 性能低(默认)

内存管理的相关参数:
1,assign:直接赋值(默认适用于非oc对象类型)
2,copy:release旧值,copy新值。
内存的管理代码规范:
  只要调用alloc,就必须有release或autorelease。如果对象不是alloc产生的,

就不用release。

set方法的代码规范:
1,基本数据类型:直接赋值
2,OC对象类型:
   先判断是否是新对象,使用新对象,对新对象加一次retain,对旧对象减一次

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

          _car = [car retain];  

      }
}

dealloc方法代码规范:
1,一定要调用[super dealloc],一定要放到最后面。
2,当前对象(self),所拥有对象做一次release.


多对象内存管理
    当你想使用某个对象的时候,你应该对他的计数器加1,不想用了减1。(有加有

减)谁retain,谁release。谁alloc,谁release。
 
补充:访问成员变量的方法有:
  直接调用
1,_成员变量;
2,self->成员变量;
  间接调用:通过get方法
3,self.成员变量;
4,[self 成员变量]

循环引用:
URL:代表资源路径
     @class 声明一个类,仅仅告诉编译器某个名称是一个类。在.h文件中用@class来声

明。

在开发中引用一个类的规范
1,在.h文件中用@class来声明类
2,在.m文件中用#import来包含类的所有东西。

例如:Car这个类被其他100个类引用着,引用这个类直接用#import
坏处;当我修改了Car其中的一点东西,其他的类就要重新拷贝,大大降低我们的编

译效率。

@class的好处:
1,解决循环引用的问题
2,提高了性能

所以为了提高编译效率,一般在头文件不用#import 特殊的是父类,因为继

承:NSObject

面试题:@class 和 @import 的区别
1,#import方式包括被引用类的所有信息,包括被引用类的变量和方法。
@class方式知识告诉编译器在.h文件中,B*b知识累的声明,具体这个类是什么意思

,这里不需要知道,等实现文件中真正要用到时,才会真正查看B类中信息。
2,如果有上百个头文件都#import了同一个文件,或者一次被#import;那么一旦最

开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍。这样的

效率也是可想而知的,而相对来讲,使用@class方式就不会出现这种问题了。
3,在.m 实现文件中,如果需要引用到被引用类的实体变量或者方法时,还需要使用

#import方式引入被引用类。

面试题:循环引用问题怎么解决
当真出现两端循环引用 解决办法是:一端用retain ,另一端用 assign.

          autorelease 半自动释放
其实autorelease并不是自动释放,他只是延迟了对象被释放的时间,等释放池被销

毁,才能做release.
基本用法:
1,autorelease 会将对象放到一个自动释放池中
2,当自动释放池(autoreleasepool{  })被释放时,会对池子里的所有对象做一个

release操作。(仅仅是一次release,池子被销毁,对象不一定会销毁)
3,autorelease会返回对象本身
4,调用完autorelease方法后,对象计数器不变 ,怎么理解这句,就是autorelease不会是对象-1,

只会把对象放到池里,是池释放时对里面所有的对象做一次-1.所以说记数器不变。


自动释放池

1,在iOS程序运行过程中,会创建无数个池子,这些池子都是以栈结构存在(先进后

出)。
2,当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池。

创建释放池有两种方式:
1,@autorelease{

    这是ios5.0后的方式
}
2,5.0之前这样创建
NSAutoreleasepool=[[NSAutoReleasePool alloc] init];
[pool release];
以前销毁释放池还有一个方法叫 drain (榨干的意思)
[pool drain]一般用在mac上,ios用release.

自动释放池其实是以栈的形式存在的,栈是以数据结构存放自动释放池的。

栈的特点:先进后出。创建第一个释放池会放在栈的最底部。

autorease好处:
    不用关心对象释放的时刻,不用关心什么时候调用release.

autorease 缺点:
    不能精确控制对象的释放时间,在开发中药做一个精确控制。

autorelease:一般只适用于占用内存比较小的对象。

什么叫占用内存比较小的对象:
      就是说你对象里面的数据类型,基本上都是int float double 这些东西。如果

你的对象里面包含了很多复杂的东西,比如说@property Car 车啊,一大堆东西,

person对象就很占用内存,因此一个person对象占用了很多对象。像这种比较大型

的对象,不要随便使用autorelease。


面试题:
@autorelease pool{
Person *p = [[Person alloc]init autorelease autorelease]
池子一销毁对你的池子做了两次release.
野指针错误。
}

autorelease
1,系统自带中,如果不含alloc,new,copy,那么这些方法返回的对象都是已经

autorelease 过的了。
[NSString stringWithFomart....]
[NSDate date] 这些不需要

创建字符串对象的方式:
1,NSString *str = @"123456"
2,NSString *str = [NSString  stringWithFormat:@“age is %d”,10];
   换串 NSNumber *number = [[NSNumber alloc]initWithInt:10];
2,开发中经常写一些类方法快速创建一个autorelease的对象,创建对象的时候不

要使用类名,要用self.
比如:
+ (id)Person
{
    return [[self alloc] init autorelease];
 
}
+ (id)PersonWithAge:(int)age;
{
    Person *p = [self Peron];
    p.age = 10;
    return p;
}
- (id)dealloc
{

   [super dealloc]
}

ARC机制(自动生成释放内存的代码)
oc中arc是编译器特性。
什么是编译器特性:
      在编译代码的时候,编译器会自动检测,那里需要插入释放内存的代码。

ARC的判断准则:
     只要没有强指针指向对象,就会释放对象。

强指针:默认情况下所有的指针都是强指针 __strong. 两个下划线组成
弱指针:决定不了对象要不要释放 __weak.

ARC好处:
   只要弱指针指向对象不存在,它会自动把弱指针清空。(不清空会有野指针错误

)。

弱指针使用场合:
循环引用,在ARC情况下,当两端循环引用的时候,一端用weak,另一端用strong。

在非ARC情况下,循环引用,一端用retain,另一端用assign。

ARC特点:
1,不允许调用 release ,retain
2,允许重写dealloc,但不允许调用[super dealloc]
3,@property的参数中retain改写成strong

Xcode 的神奇功能:
能把非 ARC的东西统一改成ARC。
Edit->refactor->convert to objective-c ->ARC
重构 ARC

在有些第三方框架中不支持ARC的

怎么看项目是不是ARC的:
        项目->build settings用放大镜 搜索auto->找编译器看object-c ARC Yes。
说明项目是ARC。

想让项目既存在ARC,有存在非ARC怎么做:
       项目->build phases->comeples sourcesc4liens->选文件名.m回车 弹出方框->在

里面打上 -fno-objc->arc 敲回车。

想要项目默认不是ARC,我们想让其中某个文件是ARC,我们的做法前几个步骤相同,就

是在弹出的方框中打上 -f-objc-arc

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值