黑马训练营--IOS学习---OC语言学习总结3

OC复习总结:

这个文件是在学习完C语言的基本用法后,回顾C语言的一些语法和易错,不易理解的一下内容,可能会存在内容不连续的情况.


本文内容,有参考自 M了个J的博客 和 lizze_yun的博客 根据自身的学习进行了部分的摘抄和扩写

原文请参考:http://www.cnblogs.com/mjios/tag/objective-c/default.html?page=1

http://blog.csdn.net/zhangyun2013?viewmode=contents

内存管理:

1、引用计数器

1->每个OC对象都有自己的引用计数器,是一个整数,表示对象被引用的次数,即有多少人正在使用这个OC对象

2->每个OC对象内部专门有4个字节的存储空间来存储引用计数器

基本数据类型都是存放在栈里,而对象都是放在堆里,存放在栈里的变量用完之后系统会自动回收它所占用的内存,但是放在堆里的对象就需要手动回收其占用的内存

方法的基本使用

1->retain:计数器+1,会返回对象本身 一般在@property处使用

2->release:计数器-1,没有返回值  一般在 setter方法和 dealloc或者主函数中使用

3->returnCount:获取当前的计数器的值

4->dealloc

*一定会先释放他所拥有的资源  对应@property如果使用retain此处要进行release

*当一个对象要被收回的时候,就会调用

*一定要调用[super dealloc],这句调用要放在最后面


其他基本概念:

1->僵尸对象:所占用内存已经被回收,僵尸对象不能再使用

   2->野指针:指向僵尸对象(不可用内存)的指针

   3->空指针:没有指向任何东西的指针(存储的东西是nilnull0),给空指针发送消息不报错


注:野指针错误:错误EXC_BAD_ACCESS:访问了一块坏的内存(已经被回收、已经不可用的内存)



内存管理原则:

1.只要某个对象还在被使用,那么这个对象就不会被回收

2.你想使用(占用)某个对象,就应该让对象的计数器加1,(让对象做一次retain操作)

3.你不想再使用(占用)某个对象,就应该让对象的计数器-1(让对象做一次release操作)

4.retain,谁release

如果你通过allocnew[mutable]copy来创建一个对象,那么你必须调用releaseautorelease换句话说,不是你创建的,就不用你去[auto]release

5.alloc,谁release

只要你调用了retain,无论这个对象是如何生成的,你都要调用release

setter方法的标准写法:


  1. - (void)setCar:(Car *)car  
  2. {  
  3.    //1.先判断是不是新传进来的对象  
  4.    if (car != _car)  
  5.     {  
  6.        //2.对旧对象做一次release  
  7.        [_car release];  
  8.   
  9.        //3.对新对象做一次retain  
  10.       _car = [car retain];  
  11.     }  
  12. }  

 3.dealloc方法的代码规范

 1->一定要[super dealloc],而且放到最后面

 2->self(当前)所拥有的其他对象做一次release


  1. - (void)dealloc  
  2. {  
  3.    [_car release]; // 当前对象的成员变量_car  
  4.    [super dealloc];  
  5. }  


3.两端循环引用解决方案

 一端用retain

一端用assign

@property (nonatomic,retain)Card *car

@property (nonatomic,assign)Person *person



@class的好处:

1.解决了循环import的问题(只需要在.h文件中用@class声明,在需要的时候,才在.m文件中import这个类)

2.提高了性能#import意思是复制,假如有很多类在头文件中都引用了Card这个类,但是一旦Card这个类改变之后,其他那些类都得重新复制一遍,性能较低,用@class的话就不需要)

 @classimport的区别:

1.#import方式会包含被引用类的所有信息,包括被引用类的变量和方法;@class方式只是告诉编译器在A.h文件中 B *b 只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中信息

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

3..m实现文件中,如果需要引用到被引用类的实体变量或者方法时,还需要使用#import方式引入被引用类


autorelease的基本用法

autorelease的好处

 。不用关心对象释放的时间

 。不用关心什么时候调用release

autorelease的使用注意

 。占用内存较大的对象不要随便使用autorelease

 。占用内存较小的对象使用autorelease,没有太大影响

autorelease实际上只是把对release的调用延迟了,对于每一次autorelease,系统只是把该对象放入了当前的autorelease pool中,当该pool被释放时,该pool中的所有对象会被调用Release(注意并不是直接销毁 只是执行一次release操作而已)


ARC

Automatic Reference Counting(自动引用计数器)

2.ARC的基本原理(判断准则):只要没有强指针指向对象,就会释放对象

指针分两种:强指针,默认情况下,所有的指针都是强指针__strong

                       弱指针,__weak


 3. ARC特点:

 1)不允许调用releaseretainretainCount

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

 3@property的参数

strong:成员变量是强指针,相当于以前retain(使用OC对象)

  weak:成员变量是弱指针,相当于以前assign(使用OC对象)

  assign:基本数据类型,直接赋值。(适用于非OC对象)

 4)以前的retain,改为用strong,其余不变

 : 以前(手动管理内存时)@property (nonatomic,retain) Car *car;

       ARC机制中改为:@property (nonatomic,strong) Car *car;


ARC的循环引用


  1. int main()  
  2. {  
  3.     Dog *d = [[Dog alloc] init];  
  4.     Person *p = [[Person alloc] init];  
  5.     p.dog = d;  
  6.     d.person = p;  
  7. }  

两个都是强指针,所以没办法被释放,解决方法: 一端用strong,一端用weak

              Dog : @property (nonatomic,strong)   Person *person;

               Person端:@property (nonatomic,weak) Dog *dog



ARC的转换功能:

如果想把非ARC转换为ARC的,那么在xcode菜单栏中的edit下的refactor中找到covert to Objective-C ARC ,选择项目进行转换即可。

如果想要某些文件是非ARC的,那么在xcode6.0.1中如下图找到编译文件,双击这个文件就会出现一个对话框,在里边写上-fno-objc-arc,即可



Block

用来保存一段代码,有时也称为代码段或代码块,它是封装了一段代码,可以在任何时候执行

定义block变量:

int (^sumBlock)(int,int); 

定义了一个叫sumBlockblock对象,它带有两个int参数,返回int

实现block的声明

sumBlock(int,int) = ^(int a, int b){

 return a + b;

 };

也可以把block变量定义和具体实现写在一起

int (^MySum)(int, int) = ^(int a, int b) {

return a+b;

};


Block可以访问局部变量,但是不能修改。

如果要修改就要加关键字:__block

也可先用typedef先声明类型,再定义变量进行赋值

typedef int (^MySum)(int,int);

MySum sum = ^(int a,int b) {

return a + b;

}; 



协议:Protocol

类遵守协议:

@interface类名 : 父类 <协议名称>

@end

协议中声明了一些方法,如果某个类遵守了这份协议,就相当于这个类可以继承到这些方法的声明,然后也必须对某些方法进行实现  

@required:方法前只要加上这个关键字,表示这个方法必须要实现(若不实现,编译器会发出警告)

@optional:这个方法不一定要实现


协议遵守协议

@protocol协议名称 <协议1,协议2>

@end


定义变量时指定协议(限制变量或属性遵守某个协议)

NSObject<myProtocol> *objc3 = [[Person alloc] init]

//只有Person类遵守myProtocol协议时 才不会报错


@property中声明的属性也可以用做一个遵守协议的限制

@property (nonatomic,strong) id<myProtocol>obj;

意味着生成set方法设置这个对象时,此对象必须要遵守myProtocol这个协议


协议的声明:

@Protocol myProtocol(协议名称);.h文件中

#import  “myProtocol.h”.m文件中



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值