黑马程序员---成长之路-----OC之基础篇ARC和类别

------<a href="http://www.itheima.com"target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流

autorlease注意及错误用法
autorelease的作用:把对象加入到自动释放池中,延迟对象的释放
使用注意:
int main(){

Person *p=[Person new];
//自动释放池
@autoreleasepool{
//1、并不是所有的放到自动释放池中的代码,产生的对象就会自动释放  如果需要释放,必须加入到自动释放池
        // Person *p=[[Person new] autorelease];
      
//如果对象调用了autorelease,但是调用autorelease的时候,没有在任何一个自动释放池中,此时该对象也不会被加入到自动释放池


      [p autorelease];


        }

 //我们只需要在自动释放池代码块中调用autorelease就可以把对象加入到自动释放池中
 //Person *p=[[Person new] autorelease];

return 0;


}


@autoreleasepool的嵌套:
自动释放池的栈结构(数据结构)和内存的栈区是不一样的
对象存在位于栈顶位置的自动释放池中(栈区是先进后出式的)
[p autorelease];这样一次其实就是释放了一次,计数器就会减1
自动释放池中不宜放占用内存比较大的对象
千万不要把大量循环操作放到同一个@autorelease中,这样会造成内存峰值的上升
int main(){


@autoreleasepool{


       @autoreleasepool{


             @autoreleasepool{
                                   [p autorelease];
                              }
                       }

                 }
        return 0;
}


autorelease错误用法:
1、连续调用多次autorelease,释放池销毁时执行两次release
2、ALLOC之后调用了autorelease,之后又调用了release。

id  instancetype
instancetype可以智能的帮我们判断赋值的指针变量的类型和方法的返回值
类型是否一致,不一致的话给个警告


ARC:
指针的分类
1、强指针:默认的情况下,所以的指针都是强指针,关键字strong
2、弱指针:  weak关键字修饰的弱指针
声明一个弱指针如下:
weak Person *p
什么事ARC:
自动引用计数器,即ARC,当ARC开启的时候,编译器将自动在代码合适的地方
插入retain,release和autorelease,而作为开发者就不用考虑编译器会报错了。
ARC:编译器特性:“垃圾回收”运行时特性
ARC工作原理及判断准则:
ARC是Objective-C编译器的特性,而不是运行时特性或者垃圾回收机制,
ARC所做的只不过是在代码编译时为我们自动在核实的位置插入release或
ARC的判断准则:
只要没有强指针指向对象,对象就会被释放。
注意:当使用ARC的时候,暂时忘记“引用计数器”,因为判断标准变了


ARC机制下特点:
1、判断是否是ARC机制


   查看项目信息   不能使用retain,release,autorelease,retainCount
   在dealloc方法中不能使用[super dealloc];
使用:
    正常创建对象,不用手动释放对象 
ARC下单对象内存管理:
1、ARC下单对象内存管理
2、强弱指针




在ARC下@property set方法参数


原子性、读写和MRC下是一样的


    MRC                 ARC
  assign               assign
  retain               strong(强指针)OC其它对象       weak(弱指针)UI控件
  copy                  copy
ARC使用特点及其注意事项:
1、不允许调用release,retain,retainCount
2、允许重写dealloc但是不允许调用[super dealloc]


ARC中,只要弱指针指向的对象不在了,就直接把弱指针做清空(赋值为nil)
weak Person*p=[[Person alloc] init]//不合理,对象一创建出来就被释放掉
对象释放掉以后,ARC把指针设置为nil


ARC的兼容和转换
1、ARC模式下如何兼容非ARC的类
让程序兼容ARC和非ARC部分。转变为非ARC -fno-objc-arc转变为ARC的,-f-objc-arc.

把ARC兼容MRC的,输入-f-objc-arc

分类(Gategory)的概念


Gategory有很多种翻译:分类、类别、类目(一般叫分类)
Gategory是OC特有的语法,其他语言没有的语法
分类的作用
在不修改原有的类的基础上增加新的方法
一个庞大的类可以分模块开发
一个庞大的类可以由多个人来编写,更有利于团队合作




使用分类的目的
1、对现有类进行扩展:
比如:你可以扩展Cocoa touch框架中的类,你在类别中增加的方法会被子类所
继承,而且在运行时跟其他的方法没有区别
2、作为子类的替代手段
不需要定义和使用一个子类,你可以通过类别直接向已有的类里增加方法
3、对类中的方法归类:
利用category把一个庞大的类划分为小块来分别进行开发,从而更好的对类
中的方法进行更新维护
使用分类的步骤:
先声明分类--->实现分类--->使用分类
注意:分类的命名规则:类名+扩展方法,如“NSString+countNum”。
分类的借口声明与类的定义十分相似,但分类不继承父类,只需要带有一个括号,
表明该分类的主要用途


分类:
一些方法的声明和实现
作用:在不修改源代码的前提下,给类增加新的功能
使用格式:


//此处声明一个类:
@interface Person:NSObject


@end
//类的实现
@implementation Person
@end


声明一个分类:
@interface 待扩展的类名 (分类的名称)
@end
Person+base  ---->分类文件的命名规则
eat run
如:


int main(){


@autoreleasepool{


       @autoreleasepool{


             @autoreleasepool{
                                   [p autorelease];
                              }
                       }

                 }
        return 0;
}




实现这个分类:
格式:
@implementation 待扩展的类名 (分类的名称)


@end


如:


@implementation Person (base)


//吃
-(void)eat{


    NSLog(@"人会吃");


       }
//跑
-(void) run{


  NSLog(@"人会跑");


         }


使用分类中的方法:
和使用类中原有的对象方法一样
但是需要把头文件包含过来
Person *p=[Person new];
[p xxx];
分类的使用注意事项:


1、分类只能增加方法,不能增加成员变量,@property(可能编译不会报错,但是运行有问题)
2、分类可以访问原来类中的成员变量
3、如果分类和原来类出现同名的方法,优先调用分类中的方法,原来类中的方法会被忽略
4、当在多个类别中有同名的方法的时候,这时候,执行的最后编译的那个类别的方法


分类的非正式协议


非正式协议的概念:
非正式协议通常定义为NSObject类别
所谓非正式协议就是类别,即凡是NSObject或者其子类Foundation框架中的类增加的类别,都是非正式协议


charaterAtIndex取得字符串对应位置的字符
@implementation NSString (countNum)
NSLog(@"self=%@",self);
int count=0
for(int i=0;i<self;i++){
                  unichar ch=[self charaterAtIndex:i]
                  if(ch>='0'&&'9'){

                            count++;


                                  }

                       }


 NSLog(@"%@字符串中有%d个数字"self,count);                   
@end

分类的延展


概念:延展类别又称为扩展(Extendsion)
扩展是分类的一个特例,括号里面为空就是扩展,新添加的方法一定要予以实现(分类里没有这个限制)
@implementation NSString ()
这种写法的类别叫匿名类别,又叫类扩展,所谓类的扩展,其实就是为一个类添加
额外的原来没有的变量、方法或者属性。

延展的特点:
1、可以在延展中定义实例变量
2、不能使用@implementation 类名() 实现类别的方法
3、可以定义私有的变量和方法




Block:


定义一个无参无返回值的block变量,并且赋值了:

void (^block变量名)()=^(){
                  代码块语句;

                       };
//优化:
void (^block变量名)()={
                  代码块语句;

                       };

//block变量的使用:
block变量名();



void (^MyBlock4)()=^(){
                  NSLog(@"xxx");


                       };


//使用block变量
myBlock4();
return 0;






有参无返回值:
格式:
void(^变量名)(参数类型及个数)=^(形参列表){


                           代码块语句;
                      };




实例:
//定义一个变量myblock2同时进行赋值
void (^myblock2)(int ,int )=^(int a,int b){
 
                   NSLog(@"a+b",a+b);

                                 }

myblock2(34,12);


myblock2=^(int x,int y){


  int m=x>y ?x:y;
  NSLog(@"max=%d",m);


        };
myblock2(34,12);





有参有返回值:
格式:
返回值类型 (^变量名)(参数类型及个数)=^(形参列表){


           代码块语句;
            return ;


          }

 int(^myblock1)(int ,int )=^(int x,int y){


          return x+y;

           };
 int sum =myblock(10,20);
  NSLog(@"sum=%d",sum);
//给变量重新赋值
myblock1=^(int x,int y){

         reyurn x*y;

       }

sum=myblock(10,20);
NSLog(@"sum=%d",sum);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值