OC语法之浅谈block
block基本介绍
block对象是一段代码,和C语言函数类似,都是在一个花括号内的一套指令,但是它没有函数名,相应位置只有一个^ 符号,^ 表示这段代码是一个block对象。下面是一个block示例:
^{
NSLog(@"这是一个block语句");
}
我们可以简单理解为函数指针,即代码块的内存地址。block常用作传值,实际上就是把block的地址传到要调用block的地方。
block一般用于回调,比oc语言的的协议代理方式简洁。举个例子,比如就是我们可以在一个类的方法中声明一个block(想象成函数指针)并直接使用,不需要给出具体实现,然后在外面调用这个类方法时再定义block即可。
当然,单纯用文字说明还是太苍白了,下面我们分几个应用场景来看一下block具体是如何使用的。
block应用场景
block一般有如下几种场景:
- block的直接使用
- block作属性
- block作方法的参数
- block作方法的返回值
下面,将逐一展开这几类情况,写几个小例子来加强学习。
block直接使用
声明和定义分开
这里,我们先声明了一个block对象sayHello,其输入参数NSString*,返回值NSString*,然后,在后面的定义给出了这个blcok的具体实现。
int main(int argc, char* argv[]) {
// block先声明后定义
NSString* (^sayHello)(NSString *);
sayHello = ^(NSString* name){
return [NSString stringWithFormat:@"Hello everyone! My name is %@.", name];
};
NSLog(@"%@", sayHello(@"James"));
}
运行结果
声明和定义放一起
当然,我们完全可以把上面两个步骤合二为一。
int main(int argc, char* argv[]) {
// block声明和定义放在一起
NSString* (^sayHello)(NSString *);
sayHello = ^(NSString* name){
return [NSString stringWithFormat:@"Hello everyone! My name is %@.", name];
};
NSLog(@"%@", sayHello(@"James"));
}
运行结果同上
block作属性
简单创建了一个类,只有一条block类型属性,然后在main函数调用此属性之前定义block块。
@interface Hello : NSObject
// 注意必须是copy!!!
@property (nonatomic, copy) NSString* (^sayHello)(NSString *);
@end
@implementation Hello
@end
int main(int argc, char* argv[]) {
Hello* hello = [[Hello alloc] init];
hello.sayHello = ^(NSString* name){
return [NSString stringWithFormat:@"Hello everyone! My name is %@.", name];
};
NSLog(@"%@", hello.sayHello(@"James"));
}
运行结果同上
block作方法的参数
block写在方法输入参数位置,在类的实现文件声明,在调用时负责具体实现,可以理解为函数指针作参数。
@interface Hello : NSObject
- (NSString *)sayHello : (NSString* (^)(NSString *))helloBlock;
@end
@implementation Hello
- (NSString *)sayHello : (NSString* (^)(NSString* name))helloBlock {
return helloBlock(@"James");
}
@end
int main(int argc, char* argv[]) {
Hello* hello = [[Hello alloc] init];
NSLog(@"%@", [hello sayHello : ^(NSString* name){
return [NSString stringWithFormat:@"Hello everyone! My name is %@.", name];
}]);
}
运行结果同上
block作返回值
block写在方法返回值位置,在类的实现文件声明,在调用时负责具体实现,可以理解为函数指针作返回值。
@interface Hello : NSObject
- (NSString* (^)(NSString *))sayHello;
@end
@implementation Hello
- (NSString* (^)(NSString *))sayHello {
return ^(NSString* name) {
return [NSString stringWithFormat:@"Hello everyone! My name is %@", name];
};
}
@end
int main(int argc, char* argv[]) {
Hello* hello = [[Hello alloc] init];
NSLog(@"%@", [hello sayHello](@"James"));
}
运行结果同上
完整demo示例
下面,我们来看一个完整的demo作为复习,里面包含了上述四种情况。话不多说,代码奉上!
MyBlock.h
// MyBlock.h
//
// Created by zhangzichen on 2020/7/13.
// Copyright © 2020 zhangzichen. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface MyBlock : NSObject
@property (nonatomic, copy) NSString* (^introduceText)(NSString*); // block作属性
- (NSString *)behaviorText : (NSString* (^)(NSString*))behaviorBlock withBehaviorID : (int)behaviorID; // block作参数
- (NSString* (^)(int))eatText; // block作返回值
@end
NS_ASSUME_NONNULL_END
MyBlock.m
// MyBlock.m
//
// Created by zhangzichen on 2020/7/13.
// Copyright © 2020 zhangzichen. All rights reserved.
//
#import "MyBlock.h"
@implementation MyBlock
// block作返回值
- (NSString* (^)(int))eatText {
return ^(int a) {
NSString * str = [NSString stringWithFormat:@"我刚才吃了%d个汉堡,有点舒服", a];
return str;
};
}
// block作参数
- (NSString*)behaviorText:(NSString* (^)(NSString*))behaviorBlock withBehaviorID:(int)behaviorID {
NSString* str;
switch (behaviorID) {
case 1 : {
str = behaviorBlock(@"现在在洗澡");
}
break;
case 2 : {
str = behaviorBlock(@"现在在睡觉");
}
break;
default : {
str = behaviorBlock(@"现在啥也没做");
}
break;
}
return str;
}
@end
main.m
// main.m
//
// Created by James
// For learning Objective-C
//
#import <Foundation/Foundation.h>
#import "MyBlock.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// block普通用法,声明和定义放在一起
NSString* (^getHelloStr)(void) = ^{
return @"Hello World";
};
NSLog(@"%@", getHelloStr());
// block普通用法,声明和定义分开
NSString* (^getHelloStr2)(void);
getHelloStr2 = ^{
return @"大家好!";
};
NSLog(@"%@", getHelloStr2());
// block作属性,根据自己的需要定义block函数体
MyBlock* myBlock = [[MyBlock alloc] init];
myBlock.introduceText = ^(NSString* name) {
NSString* str = [NSString stringWithFormat:@"我是一名ios开发程序猿,名字叫做%@", name];
return str;
};
NSLog(@"%@", myBlock.introduceText(@"James"));
// block作返回值,block写在方法返回值位置,在类的实现文件声明,在调用时负责具体实现,可以理解为函数指针作返回值
NSLog(@"%@", myBlock.eatText(5));
// block作参数,block写在方法输入参数位置,在类的实现文件声明,在调用时负责具体实现,可以理解为函数指针作参数
NSString* behaviorStr = [myBlock behaviorText:^(NSString* str) {
return str;
} withBehaviorID : 2];
NSLog(@"%@", behaviorStr);
}
return 0;
}
运行结果
上一篇: 早餐吃什么健康减肥 三款早餐轻松享瘦
下一篇: 早餐吃什么减肥 七款早餐食谱趁“早”减肥