OC-Block和协议

2018-10-11  本文已影响0人  VampireJune

什么是 Block

  1. 没有返回值,没有形参
void (^JuneBlock)() = ^(){};

// 如果block没有形参,可以省略后面的 小括号()
void (^JuneBlock)() = ^{};
  1. 有返回值,有形参
int (^JuneBlock)(int, int) = ^(int a, int b){
    return a + b;
};
  1. typedef 定义 Block
// 定义一个叫 MyBlock 的类型
// 利用 MyBlock类型 可以定义 block变量
// 利用 MyBlock类型定义出来的变量,存储的代码必须返回 int 必须接受 2个int类型的参数
typedef int (^JuneBlock)(int, int)

JuneBlock jBlock;

JuneBlock j1, j2;

j1 = ^(int a, int b){
    return a - b;
};

JuneBlock sumBlock = ^(int a, int b){
    return a + b;
};
  1. Block 访问外面变量
    1> Block 内部可以访问外面的变量
    2> 默认情况下,Block 内部不能修改外面的局部变量
    3> 给局部变量加上 __block 关键字,就可以在 Block 内部修改
int a = 10;

__block int b = 10;

void (^JuneBlock)() = ^{
  // 默认情况下,block 内不能修改外面的局部变量
  // a = 20;

  // 因为 变量 b 前面加了__block,所以变量 b 的值可以被修改 
  b = 20;
  NSLog(@"b is %d", b);
};

JuneBlock();
  1. 调用 Block 之前,一定要做判断
if(JuneBlock)
{
    JuneBlock();
}
  1. 在定义 Block 时,有形参时,写上参数名称,使用 Xcode 调此 Block 时,会有提示,直接敲回车,快速创建形参代码

Protocol 协议

// 协议声明
@protocol 协议名称
// 方法声明列表
@end

// 协议遵守协议
@protocol 协议名称 <协议1, 协议2>
// 方法声明列表
@end

// 某个类遵守协议,多个协议
@interface 类名 : 父类 <协议名,其他协议名,...>
@end 

// 定义了一个名叫 JuneProtocol 的协议
@protocol JuneProtocol <NSObject>
@end

// 某个类 .h 中使用协议
@protocol 协议名;

相当于 @class,但是具体使用时,要在 .m 文件中 #import"协议类名"
@protocol JuneProtocol <NSObject>
@end
类名<协议名> *变量名
id<协议名> 变量名
NSObject<JuneProtocol> *obj
id<JuneProtocol> obj2
// 如果没有遵守对应的协议,编译器会警告


// 要求 obj 保存的对象必须是遵守 JuneProtocol 这个协议
NSObject<JuneProtocol> *obj = [[NSObject alloc] init];

id<JuneProtocol> obj = [[NSObject alloc] init];

id 相当于 NSObject*
@property (nonatomic, weak) 类名<协议名> *属性名;
@property (nonatomic, weak) id<协议名> 属性名;

@property (nonatomic, weak) Vampire<JuneProtocol> *p;
@property (nonatomic, weak) id<JuneProtocol> obj;

代理设计模式

@property (nonatomic, weak) id<协议名> delegate;

本类对象.delegate = 某个类对象 (必须遵守并实现了协议的类对象)
协议的命名格式:xxxDelegate
所有,以后定义代理时,如下

// 定义了一个名叫 JuneDelegate 的协议
@protocol JuneDelegate <NSObject>
@optional
- (void)didSelectItemAtIndex:(NSUInteger)index withView:(JuneView *)juneView ;
@end

@interface JuneView : UIView
@property (nonatomic, weak) id<JuneDelegate> delegate;
@end

@implementation JuneView
- (void)clickItem:(UIButton *)item
{
    if ([_delegate respondsToSelector:@selector(didSelectItemAtIndex:withView:)]) {
        [_delegate didSelectItemAtIndex:item.tag withView:self ];
    }
}
@end

delegate为什么用weak或assign修饰,而不用strong修饰?

在ARC中,只要对象没有强指针就会自动释放,防止循环引用
详细解释

上一篇 下一篇

猜你喜欢

热点阅读