iOS block & 闭包
2020-12-23 本文已影响0人
青椒辣不辣
---属性
@property (copy ,nonatomic) return_type (^blockName) (var_type);
---
@property (copy ,nonatomic) long (^stringBlock)(NSString *parameter);
---
self.stringBlock = ^long(NSString *parameter) {
return parameter.length;
};
long length = self.stringBlock(@"传入的字符串计算长度");
NSLog(@"字符串长度---> %ld",length);
---
---重写getter
@property (copy ,nonatomic) long (^stringBlock)(NSString *parameter);
---
-(long (^)(NSString *))stringBlock{
return ^long(NSString *parameter){
return parameter.length;;
};
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
long length = self.stringBlock(@"传入的字符串计算长度");
NSLog(@"字符串长度---> %ld",length);
}
---
---为block类型定义别名
typedef long (^RJStringBlock)(NSString *parameter);
---
@property (assign ,nonatomic) RJStringBlock stringBlock;
---
self.stringBlock = ^long(NSString *parameter) {
return parameter.length;
};
long length = self.stringBlock(@"传入的字符串计算长度");
NSLog(@"字符串长度---> %ld",length);
---
---方法参数
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self calculateStringLength:^(NSString *parameter) {
NSLog(@"字符串长度---> %ld",parameter.length);
}];
[self calculateStringLengthBack:^double(NSString *parameter) {
return parameter.length * 5;
}];
}
---
-(void)calculateStringLength:(void(^)(NSString *parameter))stringBlock{//无返回值
... ...
if (stringBlock) {
stringBlock(@"传入的字符串计算长度");
}
}
-(void)calculateStringLengthBack:(double(^)(NSString *parameter))stringBlock{//带返回值
... ...
if (stringBlock) {
long length = stringBlock(@"传入的字符串计算长度");
NSLog(@"字符串长度---> %ld",length);
}
}
---
---链式编程
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 1
RJCalculate *calculate = [[RJCalculate alloc]init];
calculate.baseNumber = 0;
calculate.plus(5).minus(1).multiply(5).divide(2);
NSLog(@"calculate.baseNumber = %.2f",calculate.baseNumber);
// 2
[RJCalculate calculate:^(RJCalculate * _Nonnull calculate) {
calculate.plus(5).minus(1).multiply(5).divide(2);
calculate.plus(5).minus(1).multiply(5).divide(2);
}];
}
---
NS_ASSUME_NONNULL_BEGIN
@interface RJCalculate : NSObject
@property (copy ,nonatomic) RJCalculate* (^plus)(double number);
@property (copy ,nonatomic) RJCalculate* (^minus)(double number);
@property (copy ,nonatomic) RJCalculate* (^multiply)(double number);
@property (copy ,nonatomic) RJCalculate* (^divide)(double number);
@property (assign ,nonatomic) double baseNumber;
+(double)calculate:(void(^)(RJCalculate *calculate))calculateBlock;
@end
NS_ASSUME_NONNULL_END
---
@implementation RJCalculate
-(RJCalculate * _Nonnull (^)(double))plus{
return ^RJCalculate * _Nonnull(double number) {
self.baseNumber += number;
return self;
};
}
-(RJCalculate * _Nonnull (^)(double))minus{
return ^RJCalculate * _Nonnull(double number) {
self.baseNumber -= number;
return self;
};
}
-(RJCalculate * _Nonnull (^)(double))multiply{
return ^RJCalculate * _Nonnull(double number) {
self.baseNumber *= number;
return self;
};
}
-(RJCalculate * _Nonnull (^)(double))divide{
return ^RJCalculate * _Nonnull(double number) {
self.baseNumber /= number;
return self;
};
}
+(double)calculate:(void(^)(RJCalculate *calculate))calculateBlock{
if (calculateBlock) {
RJCalculate *calculate = [[RJCalculate alloc]init];
calculateBlock(calculate);
NSLog(@"result = %.2f",calculate.baseNumber);
return calculate.baseNumber;
}
NSLog(@"result = 0");
return 0;
}
@end
---
---为闭包类型定义别名
typealias closureType = () -> Void
var closureProperties : closureType?
---属性
var closureProperties :(()->(Void))?//无参数无返回值
var closureProperties2 :((_ name : NSString,_ age : Int)->(Void))?//两参数无返回值
var closureProperties3 :((_ name : NSString,_ age : Int)->(NSString))?//两参数一返回值
var closureProperties4 :((_ name : NSString,_ age : Int)->(NSString,Int))?//两参数两返回值
---
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.closureProperties = {//无参数无返回值
print("closureProperties")
}
self.closureProperties?()
closureProperties2 = { (name,age)in//两参数无返回值
print("closureProperties2" + "--" + "name:\(name)" + "--" + "age:\(age)")
}
self.closureProperties2?("谷香",18)
closureProperties3 = { (name,age)in//两参数一返回值
print("closureProperties3" + "--" + "name:\(name)" + "--" + "age:\(age)")
return "90分"
}
let score = self.closureProperties3?("稻花",16)
print("closureProperties3" + "--" + "score:\(score ?? "")")
closureProperties4 = { (name,age)in//两参数两返回值
print("closureProperties4" + "--" + "name:\(name)" + "--" + "age:\(age)")
return ("99分",66)
}
let score2 = self.closureProperties4?("飘飘",17)
print("closureProperties4" + "--" + "score:\(score2 ?? ("",0))")
}
---
closureProperties
closureProperties2--name:谷香--age:18
closureProperties3--name:稻花--age:16
closureProperties3--score:90分
closureProperties4--name:飘飘--age:17
closureProperties4--score:(99分, 66)
---
---函数
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.closureFunction {//无参数无返回值
print("closureFunction1")
}
self.closureFunction { (name, age) in//两参数无返回值
print("closureFunction2" + "--" + "name:\(name)" + "--" + "age:\(age)")
}
self.closureFunction { (name, age) -> (NSString) in//两参数一返回值
print("closureFunction3" + "--" + "name:\(name)" + "--" + "age:\(age)")
return ("99分")
}
self.closureFunction { (name, age) -> (NSString, Int) in//两参数两返回值
print("closureFunction4" + "--" + "name:\(name)" + "--" + "age:\(age)")
return ("88分",66)
}
self.closureFunction(clasese: "五年级") { (name, age) -> (NSString, Int) in
print("closureFunction5" + "--" + "name:\(name)" + "--" + "age:\(age)")
return ("100分",99)
}
}
---
func closureFunction(closureParameter:()->()) -> () {//无参数无返回值
closureParameter()
}
func closureFunction(closureParameter:(_ name : NSString,_ age : Int)->()) -> () {//两参数无返回值
closureParameter("谷香",18)
}
func closureFunction(closureParameter:(_ name : NSString,_ age : Int)->(NSString)) -> () {//两参数一返回值
let score = closureParameter("稻花",16)
print("closureFunction3" + "--" + "score:\(score)")
}
func closureFunction(closureParameter:(_ name : NSString,_ age : Int)->(NSString,Int)) -> () {//两参数两返回值
let score = closureParameter("飘飘",17)
print("closureFunction4" + "--" + "score:\(score)")
}
func closureFunction(clasese : String ,closureParameter:(_ name : NSString,_ age : Int)->(NSString,Int)) -> () {
let score = closureParameter("青草",12)
print("closureFunction5" + "--" + clasese + "--" + "score:\(score)")
}
---
closureFunction1
closureFunction2--name:谷香--age:18
closureFunction3--name:稻花--age:16
closureFunction3--score:99分
closureFunction4--name:飘飘--age:17
closureFunction4--score:(88分, 66)
closureFunction5--name:青草--age:12
closureFunction5--五年级--score:(100分, 99)
---
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 13.0, *) {
self.view.backgroundColor = UIColor.systemGray6
}
let say:(String)->Void = { (name: String)->Void in
print("hi \(name)")
}
say("亲爱的")
let say2:()->Void = {
print("hi \("宝贝")")
}
say2()
//调用方式一
loadData (finishedCallback: { (jsonData)->() in
print("闭包函数调用1:" + jsonData)
})
//调用方式二
//尾随闭包 : 如果在调用方法时,该方法的最后一个参数是一个闭包.那么该闭包可以写成尾随闭包
// 尾随闭包写法一:
loadData() { (jsonData)->() in
print("闭包函数调用2:" + jsonData)
}
//调用方式三
// 尾随闭包写法二:
loadData { (jsonData)->() in
print("闭包函数调用3:" + jsonData)
}
}
deinit {
print("deinit-=-----------------")
print(#file, #function)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// 循环引用
weak var weakSelf : UIViewController? = self
loadData2 { (jsonData) in
weakSelf?.view.backgroundColor = UIColor.red
}
// 循环引用
loadData2 { [weak self] (jsonData) in
DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
print("当前输入内容:[weak self]")
self?.view.backgroundColor = UIColor.orange
}
}
// 循环引用
loadData2 { [unowned self] (jsonData) in
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
//如果在执行该方法之前调用了[deinit]那么使用self就会报错[Thread 1: signal SIGABRT]
//Fatal error: Attempted to read an unowned reference but the object was already deallocated
//去掉定时器则不会有此错误 [unowned self]等同于[weak self]
print("当前输入内容:[unowned self]")
self.view.backgroundColor = UIColor.green
}
}
/*
[weak self] 与 [unowned self] 介绍
我们只需将闭包捕获列表定义为弱引用(weak)、或者无主引用(unowned)即可解决问题,这二者的使用场景分别如下:
如果捕获(比如 self)可以被设置为 nil,也就是说它可能在闭包前被销毁,那么就要将捕获定义为 weak。
如果它们一直是相互引用,即同时销毁的,那么就可以将捕获定义为 unowned。
*/
}
//闭包的类型写法: (参数列表) -> (返回值类型)
func loadData(finishedCallback:@escaping (_ jsonData: String)->()) -> () {
DispatchQueue.global().async {
print("正在发送网络请求:\(Thread.current)")
DispatchQueue.main.sync {
print("回调主线程,将数据回调出去:\(Thread.current)")
finishedCallback("json数据")
}
}
}
//循环引用问题
var finishedCallback : ((_ jsonData : String) -> ())?
func loadData2(finishedCallback : @escaping (_ jsonData : String) -> ()) {
self.finishedCallback = finishedCallback
DispatchQueue.global().async {
print("正在发送网络请求:\(Thread.current)")
DispatchQueue.main.sync {
print("回调主线程,将数据回调出去:\(Thread.current)")
finishedCallback("json数据")
}
}
}
---
hi 亲爱的
hi 宝贝
正在发送网络请求:<NSThread: 0x600003dad080>{number = 3, name = (null)}
正在发送网络请求:<NSThread: 0x600003df8d40>{number = 7, name = (null)}
正在发送网络请求:<NSThread: 0x600003dacfc0>{number = 6, name = (null)}
回调主线程,将数据回调出去:<NSThread: 0x600003da4a00>{number = 1, name = main}
闭包函数调用2:json数据
回调主线程,将数据回调出去:<NSThread: 0x600003da4a00>{number = 1, name = main}
闭包函数调用3:json数据
回调主线程,将数据回调出去:<NSThread: 0x600003da4a00>{number = 1, name = main}
闭包函数调用1:json数据
---swift
@objc var closureProperties :(()->(Void))?
@objc var closureProperties2 :((_ name : NSString,_ age : Int)->(Void))?
---oc
pushViewController.closureProperties = ^{
NSLog(@"----closureProperties");
};
pushViewController.closureProperties2 = ^(NSString * _Nonnull name, NSInteger age) {
NSLog(@"----closureProperties2");
};
---
---oc
@property (strong ,nonatomic) void(^block1)(void);
@property (copy ,nonatomic) long (^stringBlock)(NSString *parameter);
---swift
vc.block1 = {
}
vc.stringBlock = { (parameter) in
return 1
}
---