objective-c---ARC、block、协议(protocol)

ARC

ARC概念

  • Automatic Reference Counting :自动引用计数

ARC的判断准则

  • 只要没有强指针指向对象,就会释放对象
  • 指针分为两种
    1、强指针:默认情况下,所有的指针都是强指针 _ _strong
    2、弱指针:_ _weak

在ARC中使用@property,要注意的参数的使用

@property (nonatomic,strong) Dog *dog;

//而不用:@property (nonatomic,retain) Dog *dog;

ARC的特点

  1. 不允许调用release、retain、retainCount
  2. 允许重写dealloc,但不允许调用 [super dealloc]
  3. @property的参数
    strong :成员变量是强指针(适用于oc对象类型)
    weak :成员变量是弱指针(适用于oc对象类型)
    assign :适用于非oc对象类型

ARC和非ARC兼容问题

  1. ARC兼容非ARC 在Compile Sources 里双击需要兼容的文件,输入:-fno-objc-arc
  2. 非ARC兼容ARC 在Compile Soueces 里双击需要兼容的文件,输入:-f-objc-arc

当两端循环引用的时候,解决方案

  1. ARC
    一端用strong,另一端用weak
  2. 非ARC
    一端用retain,另一端用assign

block代码块

block的使用

  • block用来保存一段代码,block的标志: ^
  • block跟函数很像:
    1、可以保存代码
    2、有返回值
    3、有形参
    4、调用方式一样
    //定义block变量
    void (^myblock)() = ^(){   //这里因为无参数,所以 ^()可以省略()
        NSLog(@"chenfanfang");
    };

    //利用block变量调用block内部的代码
    myblock();

输出结果:
2015-03-24 21:04:20.422 oc知识点[5682:66957] chenfanfang

    //定义一个有返回值,有参数的block变量
    int (^sumblock)(int,int) = ^(int a,int b){
        return a + b;

    };

    //调用
    int sum = sumblock(10,5);
    NSLog(@"sum=%d",sum);

输出结果:
2015-03-24 21:03:19.190 oc知识点[5645:66467] sum=15

block访问外面变量

  • block内部可以访问外面的变量
  • 默认情况下,block内部不能修改外面的局部变量
  • 给局部变量加上 _ _block关键字,这个局部变量就可以在block内部修改
     int __block a = 6;
    // __block int  a = 6; 这种写法也行,自己测试出来的

    void (^myblock)() = ^(){
        a = 5;
        NSLog(@"a=%d",a);
    };
    myblock();

输出结果:
2015-03-24 21:09:25.449 oc知识点[5868:68803] a=5

block指针与函数指针

函数指针

#import <Foundation/Foundation.h>

int sum (int a,int b){
    return a + b;
}

int main(int argc, const char * argv[]) {
    //明显,这样子定义稍微麻烦,我们可以在开头用typedef,在下一个代码例子中用这种方法
    int (*p) (int,int) = sum;

    //用函数指针调用函数
    int add = p(10,5);
    NSLog(@"add=%d",add);
    return 0;
}

输出结果:
2015-03-24 21:14:12.982 oc知识点[6027:70628] add=15

#import <Foundation/Foundation.h>
typedef int(*Sump) (int,int);
int sum (int a,int b){
    return a + b;
}

int main(int argc, const char * argv[]) {
    Sump p = sum;
    //用函数指针调用函数
    int add = p(10,5);
    NSLog(@"add=%d",add);
    return 0;
}

输出结果:
2015-03-24 21:19:58.143 oc知识点[6208:72797] add=15

block与函数指针定义类似

#import <Foundation/Foundation.h>
typedef int(^myblock) (int,int);

int main()
{
    myblock sumblock = ^(int a,int b){
        return a + b;

    };
    int result = sumblock(10,3);
    NSLog(@"result=%d",result);
}

输出结果:
2015-03-25 16:45:23.808 oc知识点[1107:11143] result=13

协议(protocol)

协议与继承

//继承
:  继承父类

//协议
<> 遵守协议

protocol的格式

//协议的编写
@protocol 协议名称 

方法申明列表

@end


//某个类遵守协议
@interface 类名 : 父类 <协议名称>

@end

protocol中的参数:@required和@optional

@protocol MyProtocol 
@required    //默认的参数是required
- (void)test1;
- (void)test2;

@optional
- (void)test3;

@end

//@required:要求实现,不实现就会发出警告(默认是这种方式)
//@optional:不一定要实现

protocol的基本用途

  1. 可以用来申明一大堆方法(不能申明成员变量)
  2. 只要某个类遵守了这个协议,就相当于拥有这个协议中的所有方法申明
  3. 只要父类遵守了某个协议,就相当于子类也遵守了这个协议

遵守多个协议

一个类可以遵守多个协议,不同协议用逗号隔开

@interface 类名:NSObject <协议1 , 协议2 , 协议3>
@end

协议遵守协议

  • 一个协议可以遵守其他多个协议,多个协议之间用逗号隔开
  • 一个协议遵守了其他协议,就相当于拥有了其他协议中的方法申明
@protocol 协议名称 <协议1 , 协议2 , 协议3>
@end

基协议

  1. NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它
  2. 其实还有一个协议,名字也叫NSObject,它是一个基协议,最根本最基本的协议
  3. NSObject协议中申明很多最基本的方法,比如 description、retain、release等
  4. 建议每个新的协议都要遵守NSObject协议

对象遵守协议

//要求obj保存的对象必须是遵守MyProtocol这个协议
NSObject <MyProtocol> *obj = [[NSObject alloc] init];
//要求obj保存的对象必须遵守MyProtocol,并且继承了Person这个类
Person <MyProtocol> *obj;
//背景:obj是Person类中的一个成员变量

//要求obj这个对象的类必须遵守MyProtocol这个协议
@property (nonatomic,strong) id<MyProtocol> obj;


//主函数中,类对象的创建
Person *p = [[Person alllc] init];
p.obj = [[Dog alloc] init];

//若Dog这个类没有遵守MyProtocol这个协议,就会警告

用@protocol申明协议的用法和@class类似

若真正需要用到协议中的内容时,则在类的实现文件中(.m文件中)#import “协议”

协议:ptrotocol总结

1、协议的定义

@protocol 协议的名称 <NSObject>
方法申明列表
@end

2、如何遵守协议

  • 类遵守协议
@interface 类名 : 父类名 <协议名称1 , 协议名称2>
@end
  • 协议遵守协议
@protocol 协议名称 <其他协议名称1 , 其他协议名称2>
@end

3、协议中方法申明的关键字

  • @required (默认):要求实现,如果没有实现,会发出警告
  • @optional :不要求实现,即不管有没有实现,都不会发出警告

4、定义一个变量的时候,限制这个变量保存的对象遵守某个协议

  • 类名 <协议名称> *变量名
  • id <协议名称> 变量名
    例如:
NSObject <MyProtocol> *obj;
id <MyProtocol> obj2;

5、@property中申明的属性也可用一个遵守协议的限制

  • @property (nonatomic,strong) 类名 <协议名称> *属性名
  • @property (nonatomic,strong) id <协议名称> 属性名
    例如:
@property (nonatomic,strong) Dog <MyProtocol> *dog;
@property (nonatomic,strong) id <MyProtocol> dog2;

6、协议可以定义在单独.h文件中,也可以定义在某个类的文件中

  • 如果这个协议只用于某个类中,应该把该协议定义在该类中
  • 如果这个协议用在很多类中,就应该定义在单独文件中

7、分类可以定义在单独.h和.m文件中,也可以定义在原来类中

  • 一般情况下,都是定义在单独文件中
  • 定义在原来类中的分类,只要求能看懂语法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值