// -------------------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 块语法 , 实质就是匿名函数 , 是由 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
/*
返回值类型 (^) ( 参数类型 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, ...){
封装的代码段 ;
};
/**
block 变量名 = ^( 参数类型 1 参数名 1, 参数类型 2 参数名 2, ...){
封装的代码段 ;
};
注意
:
1.
此时参数名一定不能省略
2.
如果
block
块是有返回值的
,
需要使用关键字
return
返回数据
3.!!! 大括号后面一定要加分号
3.!!! 大括号后面一定要加分号
*/
//! block的调用
//! 格式 : block 变量名 ( 实参 1, 实参 2, ...)
//! 格式 : block 变量名 ( 实参 1, 实参 2, ...)
// block
变量在赋值的时候
,block
块中的代码是不会执行的
,
只有
block
块被调用的时候才会执行
//
练习
// 定义一个 block 块 , 实现将 NSNumber 类型的对象转换为基本数据类型 , 并将转换的结果返回
int (^exchange)( NSNumber *);
exchange = ^( NSNumber *number){
// 将 NSNumber 类型对象转换为基本数据类型
return number. intValue ; // [number intValue]
};
// 调用有返有参的 exchange 变量
// 定义一个 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 ];
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 ( @" 隔壁老王的孩子像我 " );
NSLog ( @" 隔壁老王的孩子像我 " );
};
//! 给block数据类型起别名:
//! 起别名的格式 : typedef 返回值类型 (^ 新类型名 )( 参数类型 1, 参数类型 2, ...);
//! 起别名的格式 : 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 ));
typedef int (^MYBLOCK3)( int , int );
MYBLOCK3 b3 = ^( int a, int b){
return a * b;
};
NSLog ( @"%d" , b3( 3 , 7 ));
// 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);
}];