IOS开发基础之OC的Block入门_Day09-Block

IOS开发基础之OC的Block入门_Day09-Block

block是oc的重要的基础知识,重点之重。跟协议一样重要,是进行函数回调重要手段。在后续的UI学习具有举足轻重的地位。学会基础的block,夯实基础,有的放矢。
第一天

//
//  main.m
//  Day09-Block
//
//  Created by 鲁军 on 2021/4/23.
//
/**
 BOOL
 Boolean
 class
 nil
 SEL
 id
 block
 block 是一个数据类型
 int double float char .....
  既然是1个数据类型。那么就可以声明这个数据类型的变量,所以我们完全可以 声明1个 block 类型的变量
 不同类型的变量中可以存储不同类型的数据
 那么block 类型的变量中可以存储什么样的数据呢?
 1) block 是1个数据类型,所以我们声明1个block 类型的变量
 2) block类型的变量中专门存储1段代码的,可以有参数,可以有返回值
 3.    block的变量的声明
 1) 虽然block 变量中是用来存储1段代码的,但是1个block 并不是 任意的一段代码能存进去的,而是有限定的,也就是说,在声明block变量的时候,
 必须 要指定 这个block变量的存储的代码段是否有参数,是否有返回值
 声明可1个 block 返回值是void 参数是1个int类型的
 这个时候,这个block变量中就只能存储无返回值的 并且 有1个int参数的代码段
 2) 声明block的语法格式
     返回值的类型 (^block变量的名称) (参数列表)
            void(^myBlock1)();      表示声明1个block 类型的变量叫做myBlock1 这个变量变量中只能存储没有返回值的没有参数的代码段
   int(^myBlock2)();
   int(^myBlock3)(int num1,int num2);
 3) 声明block的变量的时候, 要指定这个block的变量可以存储的代码段的返回值和参数描述
 一旦指定  这个block 只能存储这样的额代码段了,其他格式的代码段无法存储
 4.初始化block变量
 1) 原理。写1个符合。block符合要求的 代码段。存储到blick变量中就可以了
 2)代码段的书写格式
 ^返回值类型(参数列表){
     代码段;
 };
 3) 写1个无参数。无返回值 的代码段
 ^void(){
       NSLog(@"大家好,我爱你");
       NSLog(@"大家好,我恨你");
 };
 当然也可以在声明block变量的同时使用符合要求的block变量中
 void(^myBlock1)();
  myBlock1 = ^void(){
  NSLog(@"大家好,我爱你");
 NSLog(@"大家好,我恨你");
 };
 4)。 有返回值的代码段
  ^int( ){
        int num1 = 10 + 20;
        return num1;
        }  ;
 我们就可以将这段代码赋值给符合要求的block变量中
  int (^myBlock2)() = ^int () {
    int num1 = 10+20;
    return num1;
 };
 
 5) 既有参数 又有返回值的代码段
  ^int  (int num1,int num2) {
    int num2 = num2+num1;
    return num3;
 };
6 如何执行存储在block的变量的代码中
   myBlock1();
 所以我们可以将这个代码段赋值给符合要求的block变量
 6) 注意:
赋值给block的必须赋值符合block变量的要求,否则就会报错
 这个时候,我们就可以将这段代码使用赋值符号 存储到无返回值无参数的block当中去了。
 7 block的简写
  1) 如果我们写的代码段的没有返回值,那么代码段的void可以省略
     void(^myBlock1)() = ^(){
       NSLog(@"大家好,我爱你");
       NSLog(@"大家好,我恨你");
 };
 注意 我们说的是代码段的 返回值如果是void 可以省略。 ,声明block变量的返回值无论是什么都不可以省略的
 2)如果我们写的代码段没有参数,那么代码段的小括弧可以省略
        int(^myBlock2)() = ^int {
        int num1 = 10 + 20;
        return num1;
 };
 再次强调。我们说的是代码段
 所以当1个代码段即没有参数也没有返回值 的时候,只写^
 void (^myBlock_1)()= ^{
 };
 3)声明block变量的时候,如果有指定的参数,可以只写参数的类型 而不写 参数的名称
   int (^myBlock4_1)(int,int) = ^(int num1,int num2){
          int num3 = num1 + num2;
    return num3;
 };
 注意:我们说的是声明block变量的时候,再写代码段的时候,类型和名称都要写
 4) 无论代码段是否有返回值,在写代码的时候,可以不写返回值类型 省略
        如果在写代码的时候,省略了返回值。,这个时候系统会自动的确定返回值类型
 如果代码段没有任何数据,那么他会认为这个代码段是没有返回值的
 如果代码中有返回数据,返回的数据是什么类型,他就会认为这个代码段是什么类型的
 建议: 不要简写,
 int(^myBlock3_3)(int,int)=^(int num1,int num2){
     int num3 = num1 + num2;
    return num3;
 };
 7. 简化block变量的复杂定义
 typedef 的使用场景。将1个长类型定义为1个短类型
 
  3) 我们也可以使用typedef 将长的block类型定义1个短类型
          typedef  返回值类型 (^新类型)(参数列表);
       typedef void (^NewType)(); 代表重新定义了1个类型叫做NewType
       声明1个无参数无返回的block
                
 8. 关于block 块访问的外部变量的问题
 1) 在block代码块的内部可以取定义在外部的变量的值,定义在外部的局部变量和全局变量
 2)在block代码块的内部可以修改全局变量的值,不能修改定义在外部的局部变量的值
 3)如果你希望我们定义的局部变量可以允许在block代码的内部去修改,那么就为这个局部变量加1个__block的修饰符
*/
#import <Foundation/Foundation.h>
typedef void (^NewType)();
int num1 = 100;
int main(int argc, const char * argv[]) {
    __block int num2 = 200;
    NewType block1 = ^(void){
        int num3 = 300;
        num2++;
        NSLog(@"我是哈哈");
        NSLog(@"%d",num2);
      };
    block1();
    /*
    //声明1个无参数无返回的block
    typedef  void (^NewType)(); //代表重新定义了1个类型叫做NewType
    NewType block1 = ^{
        NSLog(@"haha");
    };
    NewType block2;
    typedef int (^NewType2)(int num1,int num2);
    NewType2 t1 = ^int (int num1,int num2){
        return num1 + num2;
    };
    typedef unsigned long long int itcast;
    typedef int ChinaILove;
    itcast num1 = 10;
    ChinaILove num2= 20;
    NSUInteger i = 10;
    unsigned long i1 = 20;
    */
   /*  void(^myBlock1)();
    int(^myBlock2)();
    int(^myBlock3)(int num1,int num2);
    myBlock1 = ^void(){
          NSLog(@"大家好,我爱你");
          NSLog(@"大家好,我恨你");
    };
    myBlock1();
    int (^myBlock2_1)() = ^int(){
        int num3 = 10 + 56;
        return num3;
    };
    NSLog(@"%d",myBlock2_1());
    int(^myBlock4)(int num1,int num2) =  ^int(int num1,int num2) {
                  int num3 = num2+num1;
      return num3;
   };
   int res=  myBlock4(10,11);
    NSLog(@"%d",res);*/
    return 0;
}


第2个项目

//
//  main.m
//  block作为函数的参数
//
//  Created by 鲁军 on 2021/4/24.
//
/**
 block 是1个数据类型,能不能作为参数呢,可以
 2  如何为函数定义block 类型的参数
   a. 就是在小括号中声明1个指定格式的block变量就可以了
   b 可以使用typedef 简化定义,这样看起来就不会晕
 3 如果调用带block的参数的函数呢
   a.如果要调用的函数的参数是block类型的,那么要求在调用的时候传入1个和形参block要求的代码段;
   b .调用的时候,可以先将代码段存储到1个block变量中,然后再传递这个block变量,
 也可以直接将符合要求的代码段写在小括弧中
   c .小技巧,通过xcode t提示自动生成代码段
 4 将block 作为函数的参数可以实现什么样的效果
可以将调用者自己写1段代码 传递到 函数内部区去执行
 */
#import <Foundation/Foundation.h>
typedef void (^NewType)();
//为这个参数定义1个参数,定义1个block类型的参数
//无参数无返回值的block
void test(NewType block1){
    NSLog(@"~~~~~~~~~~");
    block1();
    NSLog(@"~~~~~~~~~~");
}
void test2(int (^paramsBlock)(int num1,int num2)){
    NSLog(@"~~~~~~~~~~");
    int sum = paramsBlock(10,20);
    NSLog(@"sum = %d",sum);
    NSLog(@"~~~~~~~~~~");
}
int main(int argc, const char * argv[]) {
    
    NewType type1 = ^(void){
        NSLog(@"哈哈");
        NSLog(@"😄");
        NSLog(@"😁");
    };
    test(type1);
    test(^(void){
        NSLog(@"哈哈");
        NSLog(@"😄");
        NSLog(@"😁");
    });
    test(^{
        NSLog(@"哈哈");
        NSLog(@"😄");
        NSLog(@"😁");
    });
    test2(^int(int num1, int num2) {
        return num1 + num2;
    });
    test(^{
        NSLog(@"我爱广州小蛮腰");
        NSLog(@"北京天安门不爱");
    });
    return 0;
}

第3个项目

//
//  main.m
//  05-练习
//
//  Created by 鲁军 on 2021/4/24.
//
/*
 当方法内部需要执行1个功能,但是这个功能不确定
 那么这个时候,就使用block让调用者将这个功能的具体实现传递进来
 */
#import <Foundation/Foundation.h>
#import "CZArray.h"
int main(int argc, const char * argv[]) {
    char* contries[] = {
        "China",
        "Jpanese",
        "Aisa",
        "India",
        "Laos",
        "Turkey",
        "Vietnam",
        "Bdqweqrwfddsfsda"
    };
    CZArray *a =[CZArray new];
    [a sortWIthCountries:contries andLength:sizeof(contries) / 8];
    /**2021-04-24 15:23:04.091049+0800 05-练习[2650:65152] Aisa
     2021-04-24 15:23:04.091645+0800 05-练习[2650:65152] China
     2021-04-24 15:23:04.091882+0800 05-练习[2650:65152] India
     2021-04-24 15:23:04.091998+0800 05-练习[2650:65152] Jpanese
     2021-04-24 15:23:04.092098+0800 05-练习[2650:65152] Laos
     2021-04-24 15:23:04.092126+0800 05-练习[2650:65152] Turkey
     2021-04-24 15:23:04.092144+0800 05-练习[2650:65152] Vietnam*/
    [a sortWIthCountries:contries andLength:(sizeof(contries) / 8) andCompareBlock:^BOOL(char *country1, char *country2) {
        int res = (int)strlen(country1)-(int)strlen(country2);
        if(res>0){
            return YES;
        }
        return NO;
    }];
    for(int i=0;i<sizeof(contries)/8;i++){
        NSLog(@"%s",contries[i]);
    }
    NSLog(@"~~~~~~~~~~~~~~~~~~~");
    [a sortWIthCountries:contries andLength:(sizeof(contries) / 8) andCompareBlock:^BOOL(char *country1, char *country2) {
        int res = strcmp(country1, country2);
        return res > 0;
        
    }];
    for(int i=0;i<sizeof(contries)/8;i++){
         NSLog(@"%s",contries[i]);
     }
    return 0;
}
//
//  CZArray.h
//  05-练习
//
//  Created by 鲁军 on 2021/4/24.
//

#import <Foundation/Foundation.h>
typedef BOOL (^NewType)(char *country1,char *country2);
NS_ASSUME_NONNULL_BEGIN
@interface CZArray : NSObject
-(void) sortWIthCountries:(char*[])countries andLength:(int)len;
-(void) sortWIthCountries:(char*[])countries andLength:(int)len andCompareBlock:(NewType) compareBlock;
@end

NS_ASSUME_NONNULL_END

//
//  CZArray.m
//  05-练习
//
//  Created by 鲁军 on 2021/4/24.
//

#import "CZArray.h"
#import <string.h>
@implementation CZArray
- (void)sortWIthCountries:(char * _Nonnull *)countries andLength:(int)len{
    for(int i = 0;i<len-1;i++){
        for(int j=0;j<len-1-i;j++){
            int res = strcmp(countries[j], countries[j+1]);
            if(res>0){
                char* temp = countries[j];
                countries[j] = countries[j+1];
                countries[j+1] = temp;
            }
        }
    }
}
- (void)sortWIthCountries:(char * _Nonnull *)countries andLength:(int)len andCompareBlock:(NewType)compareBlock{
     for(int i = 0;i<len-1;i++){
        for(int j=0;j<len-1-i;j++){
//            int res = strcmp(countries[j], countries[j+1]);
            BOOL res = compareBlock(countries[j], countries[j+1]);
            if(res==YES){
                char* temp = countries[j];
                countries[j] = countries[j+1];
                countries[j+1] = temp;
            }
        }
    }
}
@end

第4个项目

//
//  main.m
//  06-练习2
//
//  Created by 鲁军 on 2021/4/24.
//

#import <Foundation/Foundation.h>
#import "CZArray.h"
typedef void (^NewType)();
NewType ttt(){
    void (^block1)() =  ^{
        NSLog(@"123dfsd");
    };
     return block1;
}

int main(int argc, const char * argv[]) {
    CZArray *a = [CZArray new];
    [a bianLiWithBlock:^(int val) {
        NSLog(@"%d",val + 1);
    }];
    NewType type = ttt();
    type();
    return 0;
}

//
//  CZArray.h
//  06-练习2
//
//  Created by 鲁军 on 2021/4/24.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface CZArray : NSObject
{
    int _arr[10];
}
-(void)bianLiWithBlock:(void(^)(int val))processBlock;
@end

NS_ASSUME_NONNULL_END

//
//  CZArray.m
//  06-练习2
//
//  Created by 鲁军 on 2021/4/24.
//

#import "CZArray.h"

@implementation CZArray
- (instancetype)init
{
    self = [super init];
    if (self) {
        for(int i=1;i<11;i++){
            _arr[i-1] = i *10;
        }
     }
    return self;
}
-(void)bianLiWithBlock:(void(^)(int val))processBlock{
    for(int i=0;i<10;i++){
        processBlock(_arr[i]);
    }
    
}
@end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值