1. Block最初设计的设计就是为了服务于 GCD,且不去管它了,显然发现如今Block的灵美已经让果农们的代码敲得更加得心应手,对它也越来爱不释手、欲罢不能了。
2. 常言道,Block一般有两种惯用写法,一个是直接使用 returnType (^BlockName)(param ……)。另外一个是使用存储类关键字typedef来简约一下。
3. 苹果的农夫们为OC语言设计了协议代理模式,又提供了Block这种对象块,对于有的实现两者皆可选择,偶尔让我错误的想起了既生瑜何生亮,好在这是个和谐的社会。
4. 这里记录一下 怎么用Block实现对象间的通讯,相对于代理协议的代码行数,确实轻盈了不少。环肥燕瘦,总有人喜欢柳腰纤细掌中轻的感觉。
5.通讯逻辑:OBJCOne很清楚自己有情绪happy属性,需要反馈feedback属性,而通讯对象是世上唯一的main。
6. 一帮情况下,block可以作为属性使用,其实它有自己的isa结构,它可以与惯常的OC对象之间相互持有(且不深究),
7. block一大特色就是持有者可以随时调用它,而它的实现并不需要定义在持有对象中,而是可以出现在任何其它应用到该持有对象的陌生对象中,(无需协议关系,即可将实现和声明搁置到不同的对象间)
8. Talk is cheap,下方代码展示的是block的一般定义和使用方法,突出的是它在不同对象或函数之间的引用关系。其中的消息传递还展示了它对比协议代理的一个优势(协议代理的前提需要对象两个,而block需要强调的是声明和函数)
#import <Foundation/Foundation.h>
typedef NSString *(^MyTypeBlock)(NSString *info, BOOL emotion);//简化
@interface OBJCOne : NSObject
@property (nonatomic, assign) MyTypeBlock typeBlock;//Block typedef属性声明01
@property (nonatomic, assign) NSString *(^ProBlock)(NSString *info, BOOL emotion);//Block属性声明
@property (nonatomic, assign) BOOL happy;
@property (nonatomic, strong) NSString *feedback;
//下面这个处理方式就是typedef 带来的一种舞姿
- (void)callBlock:(MyTypeBlock)thisBlock;
@end
@implementation OBJCOne
- (void)setHappy:(BOOL)happy {
_happy = happy;
if (nil == _typeBlock) {
if (nil == self.ProBlock) {
self.feedback = @"noBlock, nothing";
}else{
if (happy) {
self.feedback = _ProBlock(@"problock 哈哈哈哈哈",happy);
}else{
self.feedback = _ProBlock(@"problock 呜呜呜呜呜~",happy);
}
}
}else{
if (happy) {
self.feedback = _typeBlock(@"typeblock 哈哈哈哈哈",happy);
}else{
self.feedback = _typeBlock(@"typeblock 呜呜呜呜呜~",happy);
}
}
[self silentlyInHome];
}
- (void)silentlyInHome {
NSLog(@"m tell me: %@",self.feedback);
self.feedback = nil;
self.happy = !self.happy;// 情绪无常,早晚会出问题的!
}
//关联应用Block 应用关系到函数接口中
- (void)callBlock:(MyTypeBlock)thisBlock{
_typeBlock = thisBlock;
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"Hello, World!");
OBJCOne *_objcOne = [OBJCOne new];
NSString *question = @"你傻笑呀神马?";
NSString *silence = @"芳草无处,是莫须有的罪名!";
_objcOne.ProBlock = ^NSString *(NSString *info, BOOL emotion){
NSLog(@"MyProBlock: %@",info);
if (emotion == YES) {
return question;
}
return silence;
};
_objcOne.ProBlock(@"he he he ",YES);
#if 0
//执行块方法实现代码 021
_objcOne.typeBlock = ^NSString *(NSString *info, BOOL emotion){
NSLog(@"MyProBlock: %@",info);
if (emotion == YES) {
return question;
}
return silence;
};
#endif
//执行块方法实现代码 022(typedef optional)
[_objcOne callBlock:^NSString *(NSString *info, BOOL emotion) {
NSLog(@"MyProBlock: %@",info);
if (emotion == YES) {
return question;
}
return silence;
}];
_objcOne.happy = YES;
}
return 0;
}
#if 0
这里对这个充许中所进行的通讯传值做一个逻辑上的分析:
1. 从main对objcOne做了happy属性设置之后,下面的block块开始执行,
NSString *(^MyTypeBlock)(NSString *info, BOOL emotion)
self.feedback = _typeBlock(@"typeblock 哈哈哈哈哈",happy);
1. _typeBlock()其实是在main中调用了函数快,_objcOne可以通过block给main传递了两个参数(@"typeblock 哈哈哈哈哈",happy)
2. main根据block传入的连个参数做的操作是
NSLog(@"MyProBlock: %@",info);
if (emotion == YES) {
return @"你傻笑呀神马?";
}
return @"芳草无处,是莫须有的罪名!";
根据block传入的参数处理完之后,return 给 block一个字符串,而获取这个字符串的是_objcOne.
3. 接下来_objcOne 又通过main中 block调用返回的NSString值进行下一步处理。
得到通讯过程如下
main 更改_objcOne的属性,--sendMSG-->_objcOne给block传参并执行block---->
然而block的实现块是定义在main中的,所以在main中执行,并可以利用main的资源(question、silence),然后指定block的返回值,执行完毕 ----> _objcOne得到block的返回值(main给的)相当于得到了main的资源。
整个过程其实和协议代理的逻辑基本一致,不过想想main是啥,这里可以是一个对象,也可以是一个函数方法。
由此可以得出结论,这个地方block实现了协议代理逻辑功能,换做协议代理过来却不行(因为协议代理需要对象!)
#endif