【Block】
代码块:就是一个功能代码块,一块代码
【注】Block是管理程序中代码块的对象
block 本身可以有参数和返回值 同时它也可以作为参数或返回值
// block 的使用基本语法
【见block1】
#import <Foundation/Foundation.h>
// 声明一个block类型
typedef int(^SBlock)(int ,int);
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 注意
// void (^yourBlock)(int);可以看成int yourblock
// block 也是一种数据类型
// 作用: 保存一块代码
// 1. 无参 无返回值的
// void 返回值类型
// myBlock 代码块的名字
// () 参数类型 也就是形参
// ^(){ }; 代码块
void (^myBlock)() = ^(){
NSLog(@"元旦要放假了,但是我个爱好学习的人,那也要放松一下");// 元旦要放假了,但是我个爱好学习的人,那也要放松一下
};
myBlock();
// 有参 无返回值的
// (int ) 参数的类型
// (int a) 形参
void (^yourBlock)(int);
yourBlock = ^(int a){
int num = 2 * a;
NSLog(@"它的结果是:%d",num);// 它的结果是:20
};
yourBlock(10);
// 有参 有 返回值的
int (^herBlock)(int );
herBlock = ^(int m){
return m * m;
};
NSLog(@"它的平方是:%d",herBlock(100)); //它的平方是:10000
// 有返回值 多个参数
int (^hisBlock)(int,int,int) = ^(int a, int b, int c){
int num = a + b +c;
return num;
};
NSLog(@"他们的和是:%d",hisBlock(100,200,300));// 他们的和是:600
void (^ourBlock)(int ) = ^(int num){
for (int i = 0; i < num; i ++) {
NSLog(@"我们一共要打印%d次, 这是%d次",num, i + 1);// 我们一共要打印20次, 这是20次
}
};
ourBlock(20);
//有参数的
SBlock addBlock = ^(int a, int b){
return a + b;
};
NSLog(@"%d-----addBlock",addBlock(10,25)); //35-----addBlock
SBlock subBlock = ^(int a, int b){
return a - b;
};
NSLog(@"%d------subBlock",subBlock(100, 50));//50------subBlock
}
return 0;
}
// block 封装代码 使用typedef定义
【见block2】
// 声明一个block类型
typedef int(^SBlock)(int ,int);
int main(int argc, const char * argv[]) {
@autoreleasepool {
SBlock addBlock = ^(int a, int b){
return a + b;
};
NSLog(@"%d-----addBlock",addBlock(10,25));
SBlock subBlock = ^(int a, int b){
return a - b;
};
NSLog(@"%d------subBlock",subBlock(100, 50));
}
// NSLog(@"%d,-----sub%d",SBlock(2,3));
return 0;
}
//【注】__block关键字,声明一个变量,使变量在Block的内外都能使用。
【见block3】
#import <Foundation/Foundation.h>
typedef int (^MyBlcok)(int);
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 没有使用__block 修饰的变量,代码块执行的使用,使用是copy的一份。在代码块执行之前修改变量的值,不会影响代码块中变量的值
int a = 10;
MyBlcok mBlock = ^(int num) {
return num + a;
};
a = 20;
NSLog(@"%d",mBlock(10));//打印结果 20
//__block 修饰的变量,代码块里存放的是变量的地址,当变量修改时,会影响我的代码块里的变量值
__block int b = 100;
MyBlcok mmmBlock = ^(int num){
return num + b;
};
b = 200;
NSLog(@"%d",mmmBlock(100)); //打印结果 300
}
return 0;
}
//Block和函数指针很相似,可以记成将函数指针的*改成^
int (^block)(int, int);
【注】block是一个指向Block对象的指针
//block是一个Block对象指针
block = ^(int a, int b){
NSLog(@"这个代码块被使用了");
return a + b;
};
//这不是个函数,是一个代码块对象
NSLog(@"%d", block(4, 8));
// 练习
2.写一个Block,返回两个数的立方和。
// 2.写一个Block,返回两个数的立方和。
int (^subBlock)(int ,int) = ^(int a, int b){
return (int)(pow(a, 3) + pow(b, 3));
};
NSLog(@"%d",subBlock(2,3));//35
3.写一个Block,返回三个数中的最大值。
// 3.写一个Block,返回三个数中的最大值。
int (^maxBlock)(int ,int , int) = ^(int a, int b, int c){
return ((a > b) ? a:b) > c ?((a > b) ? a:b) : c;
};
NSLog(@"%d",maxBlock(1,2,3));//3
4.写一个Block,返回三个数的平均数。
// 4.写一个Block,返回三个数的平均数。
int (^avgBlock)(int ,int ,int )= ^(int a, int b,int c){
return (a + b + c)/3;
};
NSLog(@"%d",avgBlock(1,2,3));//2
// 见block练习1
【作用】Block实现回调
【Block】
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//利用block回调来进行传值: 这个程序就是描述的是一个人用迅雷去下载微电影,然后迅雷把微电影这个值返回给这个人
Person *person = [[Person alloc] init];
//人调用方法 让迅雷去下载
[person letToolBeginDownLoad];
}
return 0;
}
#import <Foundation/Foundation.h>
@interface Person : NSObject
//人要下载器去下载东西
- (void)letToolBeginDownLoad;
@end
#import "Person.h"
#import "XunLei.h"
@implementation Person
- (void)letToolBeginDownLoad
{
// 下载工具
XunLei *xunLei = [[XunLei alloc] init];
// 存起来
void (^MyBlock)(NSString *) = ^(NSString *resouce){
NSLog(@"%@",resouce);
};
// 下载工具调用下载方法
[xunLei downLoadWithBlock:MyBlock];
}
@end
#import <Foundation/Foundation.h>
//typedef <#returnType#>(^<#name#>)(<#arguments#>);
@interface XunLei : NSObject
- (void)downLoadWithBlock:(void(^)(NSString *))block;
@end
#import "XunLei.h"
@implementation XunLei
- (void)downLoadWithBlock:(void (^)(NSString *))block
{
NSLog(@"开始下载");
int i = 0;
while (i ++ < 5) {
sleep(1);
}
NSString *resouce = @"微电影";
// 调用了 人 声明的一个块代码
block(resouce);
}
@end
- ClassA给ClassB传一个字符串,ClassB逆序后返回给ClassA (分别使用代理和block实现)
#import <Foundation/Foundation.h>
#import "AClass.h"
#import "BClass.h"
#import "CClass.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
AClass *aClass = [[AClass alloc] init];
BClass *bClass = [[BClass alloc] init];
CClass *cClass = [[CClass alloc] init];
// 让 a 成为 b 的代理
bClass.delegate = aClass;
// a 排好 给 c
aClass.delegate = cClass;
// 让a把数据给b
[aClass aClassWithArray:@[@"12",@"432",@"4",@"45"] withBClass:bClass];
}
return 0;
}
#import <Foundation/Foundation.h>
#import "BClass.h"
@class AClass;
@protocol AClassDelegate <NSObject>
- (void)aClass:(AClass *)aClass array:(NSArray *)array;
@end
@interface AClass : NSObject<BClassDelegate>
@property (nonatomic, weak)id<AClassDelegate>delegate;
- (void)aClassWithArray:(NSArray *)array withBClass:(BClass *)bClass;
@end
#import "AClass.h"
@implementation AClass
- (void)aClassWithArray:(NSArray *)array withBClass:(BClass *)bClass
{
// 数组给B
bClass.array = array;
}
- (void)bClass:(BClass *)bClass array:(NSArray *)array
{
// 1. 获取到了数组
// 2. 排序
// 3. 排好序的给C
if ([_delegate respondsToSelector:@selector(aClass:array:)]) {
[_delegate aClass:self array:array];
}
}
@end
#import <Foundation/Foundation.h>
@class BClass;
@protocol BClassDelegate <NSObject>
// 第一个参数一般是把自己传过去
- (void)bClass:(BClass *)bClass array:(NSArray *)array;
@end
@interface BClass : NSObject
@property (nonatomic, weak)id<BClassDelegate>delegate;
@property (nonatomic, strong)NSArray *array;
@end
#import "BClass.h"
@implementation BClass
- (void)setArray:(NSArray *)array
{
//1. 排序
//2. 返回给A
if ([_delegate respondsToSelector:@selector(bClass:array:)]) {
[_delegate bClass:self array:array];
}
}
@end
#import <Foundation/Foundation.h>
#import "AClass.h"
@interface CClass : NSObject<AClassDelegate>
@end
#import "CClass.h"
@implementation CClass
- (void)aClass:(AClass *)aClass array:(NSArray *)array
{
NSLog(@"%@",array);
}
@end
- 创建一个Person 想要买东西,使用Buyer 去买。卖完后,Buyer把值传给Person
#import <Foundation/Foundation.h>
#import "BClass.h"
#import "AClass.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 让B去偷东西,把偷到得东西给A
AClass *a = [[AClass alloc] init];
[a letSomeBodySteal];
}
return 0;
}
#import <Foundation/Foundation.h>
#import "BClass.h"
@interface AClass : NSObject<BClassDelegate>
- (void)letSomeBodySteal;
@end
#import "AClass.h"
@interface AClass ()
{
BClass *_twoB;
}
@end
@implementation AClass
- (void)letSomeBodySteal
{
_twoB = [[BClass alloc] init];
NSLog(@"慢慢的靠近");
NSLog(@"突然撞你一下");
NSLog(@"瞅了一眼");
//这里的self表示的是a指针,因为在主函数里面是a指针调用的这个函数
_twoB.delegate = self;
NSLog(@"B 偷到巨额的金钱");
[_twoB stealWithStr:@"0.1元"];
}
- (void)catchMoney:(NSString *)money
{
NSLog(@"A获取到了%@",money);
NSLog(@"挖个坑,埋起来,此地无钱");
}
@end
#import <Foundation/Foundation.h>
@protocol BClassDelegate <NSObject>
- (void)catchMoney:(NSString *)money;
@end
@interface BClass : NSObject
// 代理属性设置使用 weak
@property (nonatomic,weak)id<BClassDelegate>delegate;
- (void)stealWithStr:(NSString *)str;
@end
#import "BClass.h"
@implementation BClass
- (void)stealWithStr:(NSString *)str
{
// 防止方法找不到,程序出问题
if ([_delegate respondsToSelector:@selector(catchMoney:)]) {// 代理如果实现了这个方法
// 把偷到的💰给A
[_delegate catchMoney:str];
}
}
@end
// 作业
让A B拥有5个相同的方法
让A用有一份协议,其中有2个必须实现的方法,3个不要要求的方法
一个人有一条狗,狗饿了,人喂食。
-
有一组数字,A传给B,
B使用冒泡算法从大到小排好序后,返回给A,
A拿到组数据后使用选择排序从小到大排序传给C(分别使用代理和block实现)
- 模拟下载数据,B下载完数据后,A进行处理