您的位置:首页 > 其它

Block

2015-11-26 22:18 288 查看
// -------------------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);

//!
[b]如何给
block变量赋值(block语法的实现)[/b]

/**

block变量名 = ^(参数类型1
参数名1,
参数类型2
参数名2, ...){

封装的代码段;

};

注意:

1.
此时参数名一定不能省略
2.
如果block块是有返回值的,需要使用关键字return返回数据

3.!!!大括号后面一定要加分号
*/

//! block[b]的调用[/b]

//! 格式: 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);
*/

//!
[b]定义
block变量的同时可以赋值:[/b]

void (^myBlock5)() = ^(){

NSLog(@"隔壁老王的孩子像我");

};

//!
[b]给
block数据类型起别名:[/b]

//! 起别名的格式: 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);
}];
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: