美文网首页
iOS block & 闭包

iOS block & 闭包

作者: 青椒辣不辣 | 来源:发表于2020-12-23 16:42 被阅读0次

\color{rgb(0 ,139, 139)}{OC-block}

---属性
@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
---

\color{rgb(0 ,139, 139)}{swift-闭包}

---为闭包类型定义别名
    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数据

\color{rgb(0 ,139, 139)}{OC中调用swift-闭包}

---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");
    };
---

\color{rgb(0 ,139, 139)}{swift中调用OC-block}

---oc
@property (strong ,nonatomic) void(^block1)(void);
@property (copy ,nonatomic) long (^stringBlock)(NSString *parameter);
---swift
        vc.block1 = {
            
        }
        vc.stringBlock = { (parameter) in
            return 1
        }
---

相关文章

网友评论

      本文标题:iOS block & 闭包

      本文链接:https://www.haomeiwen.com/subject/euusnktx.html