博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Block
阅读量:4087 次
发布时间:2019-05-25

本文共 6529 字,大约阅读时间需要 21 分钟。

 

// -------------------block
语法
-----------------------------------------
   
// block
块语法
,
实质就是匿名函数
,
是由
C
语言中的函数扩充而来
   
// block
也可以保存一段特定功能的代码段
,
也就是我们封装好的特定功能代码
   
// block
语言底层是由
C
语言实现的
,
所以执行效率很高
,
也是苹果非常推崇的一种语法
   
// GCD:  Grand Central Dispatch
Apple
开发的一个多核编程的解决方法
   
/*
    
     Grand Central Dispatch
简称(
GCD
)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统。这建立在任务并行执行的线程池模式的基础上的。它首次发布在
Mac OS X 10.6
iOS 4
及以上也可用。
    
设计:
     GCD
的工作原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。
    
一个任务可以是一个函数
(function)
或者是一个
block
GCD
的底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节。
     GCD
中的
FIFO
队列称为
dispatch queue
,它可以保证先进来的任务先得到执行
    
     */
   
// block
语法的实现其实是借鉴了函数指针的语法
    

   
// block
的数据类型
   
/*
    
返回值类型
(^) (
参数类型
1
参数名
1,
参数类型
2
参数名
2, ...); //
参数名可以省略
,
但是参数类型一定不能省
    
注意
:
如果定义的
block
块中没有参数
,
小括号也不能省略
    
     block
一共分为四大类
    
无返无参的
block
    
无返有参的
block
    
有返无参的
block
    
有返有参的
block
       
     */
//
定义
block
变量格式
:
返回值类型
(^
变量名
)(
参数类型
1,
参数类型
2, ...);
  • void (^myBlock)();
  • void (^myBlock2)(int, int);
  • int (^myBlock3)();
  • int (^myBlock4)(int, int);
//! 如何给block变量赋值(block语法的实现)
   
/**
        block
变量名
= ^(
参数类型
1
参数名
1,
参数类型
2
参数名
2, ...){
               
封装的代码段
;
     };
    
    
注意
:
     1.
此时参数名一定不能省略
     2.
如果
block
块是有返回值的
,
需要使用关键字
return
返回数据
     3.!!!
大括号后面一定要加分号
     */
//! block的调用
   
//!
格式
: block
变量名
(
实参
1,
实参
2, ...)
    // block
变量在赋值的时候
,block
块中的代码是不会执行的
,
只有
block
块被调用的时候才会执行
//
练习
   
//
定义一个
block
,
实现将
NSNumber
类型的对象转换为基本数据类型
,
并将转换的结果返回
   
int
(^exchange)(
NSNumber
*);
   
    exchange = ^(
NSNumber
*number){
       
//
NSNumber
类型对象转换为基本数据类型
       
return
number.
intValue
;
// [number intValue]
    };
   
   
//
调用有返有参的
exchange
变量
    NSLog(@"number1 = %d", exchange(@100));
/*
//
数字字符串对象
也可以
转为
基本数据类型
   
NSString
*intNumber =
@"1001"
;
   
NSLog
(
@"%d"
, intNumber.
intValue
);
   
   
// float
字符串对象
转为
基本数据类型
   
NSString
*floatString =
@"3.14"
;
   
NSLog
(
@"%.2f"
, floatString.
floatValue
);
   
   
//
把基本数据类型
转换为
对象类型
(
字符串
)
   
NSString
*doubleString = [
NSString
stringWithFormat
:
@"%f"
,
3.141592
];
    NSLog(@"%@", doubleString);
*/
//! 定义block变量的同时可以赋值:
   
void
(^myBlock5)() = ^(){
     
       
NSLog
(
@"
隔壁老王的孩子像我
"
);
       
    };

//!    block数据类型起别名:
   
//!
起别名的格式
: typedef
返回值类型
(^
新类型名
)(
参数类型
1,
参数类型
2, ...);
    //
给函数指针类型起别名
typedef int(*FUN)(int, int);
    myB
//
int (^)(int, int)
起别名
   
typedef
int
(^MYBLOCK3)(
int
,
int
);
   
MYBLOCK3
b3 = ^(
int
a,
int
b){
       
return
a * b;
    };
   
NSLog
(
@"%d"
, b3(
3
,
7
));

// block
中可以访问局部变量
,
但是不能修改局部变量
.
如果非要修改局部变量的值
,
此时在定义这个局部变量的时候使用
__block
修饰
// block
块中可以直接访问且修改全局变量
;

// ---------------------------------------------block
作为方法的参数
NSArray *array = @[@"1", @"2", @"3", @"4", @"5", @"3"]; // 笑笑语法    // 找出数组中@"3",输出    for (NSString *str in array) {        if ([str isEqualToString:@"3"]) {            NSLog(@"str = %@", str);            break;        }    }        // 第一个参数obj 枚举得到的数组元素    // 第二个参数idx 枚举出数组元素的下标    // 第三个参数stop 枚举停止的条件        [array enumerateObjectsUsingBlock:^(NSString * obj, NSUInteger idx, BOOL *stop) {        if ([obj isEqualToString:@"3"]) {            NSLog(@"%@ %lu", obj, idx);            *stop = YES;        }        // 如果 *stop = YES ,就会结束这个快速枚举, *stop默认是NO            }];        //! 以上两种方法都可以 forin 和 enumerateObjectsUsingBlock        // ************************************    NSDictionary *dic = @{@"1":@"a", @"2":@"b", @"3":@"c"};    for (NSDictionary *key in dic) {        NSLog(@"%@ = %@", key, dic[key]); // (笑笑语法)dic[key] == [dic objectForKey:key]    }        // 字典的block块遍历    // 第一个参数 字典中的key    // 第二个参数 字典中key对应的value值    // 第三个参数 枚举结束的条件    [dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {        NSLog(@"%@ - %@", key, obj);        //*stop = YES;    }];    // ***********************************            // --------------使用block作为方法的参数完成数组的排序    NSArray *arr = @[@"2", @"1", @"4", @"3", @"8", @"5"];    // ---方法一:数组排序(这种只能升序)    NSArray * sortArray = [arr sortedArrayUsingSelector:@selector(compare:)];    NSLog(@"%@", sortArray);        // ---方法2 : sortedArrayUsingComparator    // 参数obj1 和 obj2 是数组中两个相邻的元素    // 此方法排序根据block块中返回值是NSOrderedAscending对应的判断条件为准,让相邻的两个元素交换位置(与 NSOrderedAscending,NSOrderedSame 无关)    NSArray *sortArray2 = [arr sortedArrayUsingComparator:^NSComparisonResult(NSString * obj1, NSString * obj2) {                if (obj1.intValue > obj2.intValue) {                        return NSOrderedDescending;                    }else if (obj1.intValue < obj2.intValue) {                        return NSOrderedAscending;                    }else {                        return NSOrderedSame;                    }    }];    NSLog(@"%@", sortArray2);          // -----------------------------------------------------    // 创建4个Person对象    Person *per1 = [Person personWithName:@"yangMi" gender:@"男" age:25 height:1.68];    Person *per2 = [Person personWithName:@"lishishi" gender:@"女" age:30 height:1.66];    Person *per3 = [Person personWithName:@"yangYang" gender:@"男" age:24 height:1.80];    Person *per4 = [Person personWithName:@"sunLi" gender:@"女" age:33 height:1.69];    NSArray *pArr = @[per1, per2, per3, per4];        // 根据姓名排序    NSArray *sortName = [pArr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { // 参数obj1 和 obj2 是数组中两个相邻的元素        // id类型是点不出对象的实例变量,所以需要把id类型 的对象转为 Person* 类型的 // 或者将id改为对应的数据类型        Person *p1 = obj1;        Person *p2 = obj2;        // 前一个人的名字比后一个人的名字大        if ([p1.name compare:p2.name] == NSOrderedDescending) {            return NSOrderedDescending;        }else if ([p1.name compare:p2.name] == NSOrderedAscending) {            return NSOrderedAscending;        }else {            return NSOrderedSame;        }    }];        [sortName enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {        NSLog(@"%@", obj);    }];    NSLog(@"------------");    // 根据年龄排序    NSArray *sortAge = [pArr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {        Person *p1 = obj1;        Person *p2 = obj2;        if (p1.age > p2.age) {            return NSOrderedDescending;        }else if (p1.age < p2.age) {            return NSOrderedAscending;        }else {            return NSOrderedSame;        }    }];        [sortAge enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {        NSLog(@"%@", obj);    }];        NSLog(@"------------");        // 根据身高排序    NSArray *sortHeight = [pArr sortedArrayUsingComparator:^NSComparisonResult(Person* obj1, Person* obj2) {        if (obj1.height > obj2.height) {            return NSOrderedAscending;        }else if (obj1.height < obj2.height) {            return NSOrderedDescending;        }else {            return NSOrderedSame;        }    }];        [sortHeight enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {        NSLog(@"%@", obj);    }];

转载地址:http://xcuii.baihongyu.com/

你可能感兴趣的文章
【Lua】Mac系统下配置SublimeText的Lua编译环境
查看>>
【C#】利用Conditional属性完成编译忽略
查看>>
【Unity】微信登录后将头像存为bytes,将bytes读取成sprite图片
查看>>
【Unity】使用GPS定位经纬度
查看>>
【UGUI/NGUI】一键换Text/Label字体
查看>>
【C#】身份证本地验证
查看>>
【Unity】坑爹的Bug
查看>>
【算法】求数组中某两个数的和为目标值
查看>>
如何高效学习动态规划?
查看>>
动态规划法(六)鸡蛋掉落问题(一)
查看>>
LeetCode 887.鸡蛋掉落(C++)
查看>>
Dijkstra‘s algorithm (C++)
查看>>
奇异值分解(SVD)的原理详解及推导
查看>>
算法数据结构 思维导图学习系列(1)- 数据结构 8种数据结构 数组(Array)链表(Linked List)队列(Queue)栈(Stack)树(Tree)散列表(Hash)堆(Heap)图
查看>>
求LCA最近公共祖先的离线Tarjan算法_C++
查看>>
Leetcode 834. 树中距离之和 C++
查看>>
【机器学习】机器学习系统SysML 阅读表
查看>>
最小费用最大流 修改的dijkstra + Ford-Fulksonff算法
查看>>
最小费用流 Bellman-Ford与Dijkstra 模板
查看>>
实现高性能纠删码引擎 | 纠删码技术详解(下)
查看>>