1.iOS中,block怎么定义
block是一个代码块,比如一些其它Web编程语言中的“匿名函数”。在objc中通常使用block实现代理方法实现的功能,也就是回调。使用代理需要设置代理的数据接收者,而且代理方法是被分离开来处理的,block可以将这些分离的代码放到一个代码块中。
/////////.h
typedef void(^MyBlock)(int value);
@property (nonatomic,weak) MyBlock block;
-(void)setMyBlock:(void(^)(int value)) block;
/////////.m
-(void)setMyBlock:(void(^)(int value)) block {
if (block) {
self.block=block;
}
}
2.如何在iOS中使用Block
Block可以帮助我们组织独立的代码段,并提高复用性和可读性。
iOS4在UIKit中引入了该特征。超过100个的Apple API都使用了Block,所以这是一个我们必须开始熟悉的知识。
Block是什么样的? 你可以使用^操作符来声明一个Block变量,它表示一个Block的开始。 int num1 = 7; int(^aBlock)(int) = ^)int num2) { return num1+nunm2; }; 在如上代码中我们将Block声明为一个变量,所以可以将它当做一个函数中使用: NSLog(@"%d", aBlock(49)); //adds 49 to 7 which gives us 56. 我们刚看过了将block当做变量的情况,但通常情况下我们会以内联的方式使用Block,比如在一个变量中。
API要么会使用Block在一个对象集合上执行某种操作,要么将其作为一个操作完成后的回调。 NSComperator compareStringsBlock = ^(id stringA, id stringB) { NSRange rangeS = NSMakeRange (0, [stringA length]); return (stringA compare:stringB options:comparisonOptions range:rangeS locale:currentLocale]; }; NSArray *compareSortArray = [arrayOfStringDays : compareStringsBlock]); Block具有将临时函数体创建为表达式的优势。
Apple文档中指出: Block是符合如下要求的匿名内联的代码集: 和函数一样具有一个指定类型的参数列表 有一个可以推导或声明的返回值类型 可以从它被定义的词义范围中捕捉状态 可以在需要的时候改变词义范围的状态 可以和相同的词义范围中定义的其他的Block共享更改的可能。 可以在词义范围(堆栈帧)被销毁后继续共享和修改该词义范围(堆栈帧)的状态。
Block是一个自包含的小代码段,封装了用于遍历(线性遍历)或者回调,可以并发执行的任务单元。 声明和使用Block Apple文档中介绍了如何将一个Block声明为变量,并将其作为一个函数使用: int (^oneFrom)(int) = ^(int anInt) { return anInt - 1; }; // 我们创建了一个内联块^(int anInt)。
,其函数体和结果被传到了另外一个名为OneFrom的Block。 printf("1 from 10 is %d", oneFrom(10)); // 打印出: "1 from 10 is 9" // 这个block函数(distanceTraveled)传入3个float型参数,返回float值。
float (^distanceTraveled) (float, float, float) = ^(float startingSpeed, float acceleration, float time) { float distance = (startingSpeed * time) + (0.5 * acceleration * time * time); return distance; }; 你也可以传入一个Block作为一个参数,而不要以如上的方式声明它们,这样就可以在需要将block作为参数的时候以内联代码的方式简单地实现。 NSArray *anArray = [NSArray arrayWithObjects: @"cat", @"dog",nil]; sortFunction(anArray, ^(string *a string *b){ if ( a == @"cat") return TRUE; }); 这样我们就看到一个内联的block代码段占据了最后一个参数(必须是参数列表的最后一个参数)的位置。
Cocoa提供了很多使用Block的方法,这样你就可以传入Block作为方法的参数: NSArray *array = [NSArray arrayWithObjects: @"A", @"B", @"C", nil]; NSSet *filterSet = [NSSet setWithObjects: @"A", @"Z", @"Q", nil]; BOOL (^test)(id obj, NSUInteger idx, BOOL *stop); //Block declaration returns BOOL, params inc. id and BOOL //body of block gets the block literal ^(id obj, NSUInteger idx, Bool *stop)。 and the body logic test = ^ (id obj, NSUInteger idx, BOOL *stop) { if (idx < 5) { if ([filterSet containsObject: obj]) { return YES; } } return NO; }; Apple提供的另外一个例子是: __block BOOL found = NO; NSSet *aSet = [NSSet setWithObjects: @"Alpha", @"Beta", @"Gamma", @"X", nil]; NSString *string = @"gamma"; //we provide below a way of how to enumerate, using our own compare logic [aSet :^(id obj, BOOL *stop) { if ([obj :string] == NSOrderedSame) { *stop = YES; found = YES; } }]; As you can see, it takes a little while to have it sink in but once you get it, it's quite simple. I suggest looking at Apple's documentation, as well as looking at the referenced APIs to see how they are used. Practice makes perfect. 原文出处:/topic/2281-how-to-use-blocks-with-ios/ objective-c block 详解 Block Apple 在C, Objective-C, C++加上Block这个延申用法。
目前只有Mac 10.6 和iOS 4有支援。Block是由一堆可执行的程式组成,也可以称做没有名字的Function (Anonymous function)。
如果是Mac 10.6 或 iOS 4.0 之前的平台可以利用 /p/plblocks/ 这个project得以支援Block语法。 Apple有一个叫做GCD(Grand Central Dispach)的新功能,用在同步处理(concurrency)的环境下有更好的效率。
Block语法产生的动机就是来自於GCD,用Block包好 一个工作量交给GCD,GCD有一个宏观的视野可以来分配CPU,GPU,Memory的来下最好的决定。 Block 简介 Block其实行为和Function很像,最大的差别是在可以存取同一个Scope的变数值。
Block 实体会长成这样 ^(传入参数列) {行为主体}; Block实体开头是"^",接著。
3.ios block是什么数据类型
block定义 struct Block_descriptor { unsigned long int reserved; unsigned long int size; void (*copy)(void *dst, void *src); void (*dispose)(void *); }; struct Block_layout { void *isa; int flags; int reserved; void (*invoke)(void *, 。
); struct Block_descriptor *descriptor; /* Imported variables. */ }; 实际上block就是这俩玩意了 我们来举个栗子看看 定义一个最简单block 打印hello world 使用clang指令 clang -rewrite-objc main.m 得到一个cpp文件 打开之,你就会看到什么是block了 你定义完block之后,其实是创建了一个函数,在创建结构体的时候把函数的指针一起传给了block,所以之后可以拿出来调用。再看看值捕获的问题定义block的时候,变量a的值就传递到了block结构体中,仅仅是值传递,所以在block中修改a是不会影响到外面的a变量的。
定义block的时候,变量a的值就传递到了block结构体中,仅仅是值传递,所以在block中修改a是不会影响到外面的a变量的。而加了__block前缀并不是直接传递a的值了,而是把a的地址传过去了,所以在block内部便可以修改到外面的变量了。
并不是直接传递a的值了,而是把a的地址传过去了,所以在block内部便可以修改到外面的变量了。根据isa指针,block一共有3种类型的block _NSConcreteGlobalBlock 全局静态 _NSConcreteStackBlock 保存在栈中,出函数作用域就销毁 _NSConcreteMallocBlock 保存在堆中,retainCount == 0销毁 而ARC和MRC中,还略有不同。
4.iOS开发,方法和block的结合使用,写个小demo
使用Block的地方很多,其中传值只是其中的一小部分,下面介绍Block在两个界面之间的传值:先说一下思想:首先,创建两个视图控制器,在第一个视图控制器中创建一个UILabel和一个UIButton,其中UILabel是为了显示第二个视图控制器传过来的字符串,UIButton是为了push到第二个界面。
第二个界面的只有一个UITextField,是为了输入文字,当输入文字,并且返回第一个界面的时候,当第二个视图将要消失的时候,就将第二个界面上TextFiled中的文字传给第一个界面,并且显示在UILabel上。其实核心代码就几行代码:下面是主要代码:(因为我是用storyBoard创建的工程,所以上面的属性和相应的方法,是使用系统生成的outlet)一、在第二个视图控制器的.h文件中定义声明Block属性?123456789typedef void (^ReturnTextBlock)(NSString *showText);@interface : UIViewController@property (nonatomic, copy) ReturnTextBlock returnTextBlock;- (void)returnText:(ReturnTextBlock)block;@end第一行代码是为要声明的Block重新定义了一个名字?1ReturnTextBlock这样,下面在使用的时候就会很方便。
第三行是定义的一个Block属性第四行是一个在第一个界面传进来一个Block语句块的函数,不用也可以,不过加上会减少代码的书写量二、实现第二个视图控制器的方法?123456789- (void)returnText:(ReturnTextBlock)block { self.returnTextBlock = block;}- (void)viewWillDisappear:(BOOL)animated { if (self.returnTextBlock != nil) { self.returnTextBlock(self.inputTF.text); }}其中inputTF是视图中的UITextField。第一个方法就是定义的那个方法,把传进来的Block语句块保存到本类的实例变量returnTextBlock(.h中定义的属性)中,然后寻找一个时机调用,而这个时机就是上面说到的,当视图将要消失的时候,需要重写:?1- (void)viewWillDisappear:(BOOL)animated;方法。
三、在第一个视图中获得第二个视图控制器,并且用第二个视图控制器来调用定义的属性如下方法中书写:?12345678910- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ // Get the new view controller using [segue ]. // Pass the selected object to the new view controller. *tfVC = segue.; [tfVC returnText:^(NSString *showText) { self.showLabel.text = showText; }];}。
5.ios block外怎么调用block中的值
准备工作的界面截图如下图所示。
现在的block传值是从后往前传值和代理差不多,所以,现在我们在SecondViewController.h文件中定义block再@interface上面重新定义blocktypedef void (^ReturnTextBlock)(NSString *showText);然后声明block属性@property (nonatomic, copy) ReturnTextBlock returnTextBlock;然后写一个方法,这个方法第一个界面会用到。- (void)returnText:(ReturnTextBlock)block;SecondViewController.h文件中就写这些了,我们再到SecondViewController.m文件中再.m文件中,我们先实现.h中声明的方法- (void)returnText:(ReturnTextBlock)block { self.returnTextBlock = block;}这个方法是,把block赋值给我们新创建的,未实例化得returnTextBlock然后在视图将要消失的时候,我们把值传给第一个界面- (void)viewWillDisappear:(BOOL)animated { if (self.returnTextBlock != nil) { self.returnTextBlock(self.pa.text); }}第二个界面的工作,就这么完成了,我们转到第一个界面。
首先引用第二个界面然后把,textfild和button都映射到.m文件中,映射后的结果如图所示。然后我们实现跳转(button)的点击事件,- (IBAction)tiaozhuan:(UIButton *)sender { SecondViewController *sec = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] :@"a"]; [sec returnText:^(NSString *showText) { self.pass.text = showText; }]; [self.navigationController pushViewController:sec animated:YES];}在点击事件中添加 SecondViewController *sec = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] :@"a"]; [sec returnText:^(NSString *showText) { self.pass.text = showText; }]; [self.navigationController pushViewController:sec animated:YES]; SecondViewController *sec = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] :@"a"];这句话是获取SecondViewController。
[sec returnText:^(NSString *showText) { self.pass.text = showText; }];这句话是,调用方法returnText:并传值为^(NSString *showText) { self.pass.text = showText; }传的这个block,就赋值给了第二个界面的self.returnTextBlock。然后[self.navigationController pushViewController:sec animated:YES];跳转到第二个界面。
运行结果为。
6.ios block是什么数据类型
千峰扣丁学堂iOS开发为您解答:Block是一种比较特殊的数据类型。
它可以保存一段代码,在合适的时候取出来调用。Block的修饰ARC情况下1.如果用copy修饰Block,该Block就会存储在堆空间。
则会对Block的内部对象进行强引用,导致循环引用。内存无法释放。
解决方法:新建一个指针(__weak typeof(Target) weakTarget = Target )指向Block代码块里的对象,然后用weakTarget进行操作。就可以解决循环引用问题。
2.如果用weak修饰Block,该Block就会存放在栈空间。不会出现循环引用问题。
MRC情况下用copy修饰后,如果要在Block内部使用对象,则需要进行(__block typeof(Target) blockTarget = Target )处理。在Block里面用blockTarget进行操作。
返回值类型(^block变量名)(形参列表) = ^(形参列表) {};调用Block保存的代码block变量名(实参);默认情况下,Block内部不能修改外面的局部变量Block内部可以修改使用__block修饰的局部变量Block的模式1、无参数无返回值的Block2.有参数无返回值的Block3、有参数有返回值的Block。
7.如何在 iOS 5 中使用 Block
声明和使用Block:Apple文档中介绍了如何将一个Block声明为变量,并将其作为一个函数使用:int (^oneFrom)(int) = ^(int anInt) { return anInt - 1; }; // 创建了一个内联块^(int anInt)。
,其函数体和结果被传到了另外一个名为OneFrom的Block。 printf("1 from 10 is %d", oneFrom(10)); // 打印出: "1 from 10 is 9" // 这个block函数(distanceTraveled)传入3个float型参数,返回float值。
float (^distanceTraveled) (float, float, float) = ^(float startingSpeed, float acceleration, float time) { float distance = (startingSpeed * time) + (0.5 * acceleration * time * time); return distance; }; 也可以传入一个Block作为一个参数,而不要以如上的方式声明,这样就可以在需要将block作为参数的时候以内联代码的方式简单地实现。NSArray *anArray = [NSArray arrayWithObjects: @"cat", @"dog",nil]; sortFunction(anArray, ^(string *a string *b){ if ( a == @"cat") return TRUE; });。
8.ios block外怎么调用block中的值
准备工作的界面截图如下图所示。
现在的block传值是从后往前传值和代理差不多,所以,现在我们在SecondViewController.h文件中定义block再@interface上面重新定义blocktypedef void (^ReturnTextBlock)(NSString *showText);然后声明block属性@property (nonatomic, copy) ReturnTextBlock returnTextBlock;然后写一个方法,这个方法第一个界面会用到。- (void)returnText:(ReturnTextBlock)block;SecondViewController.h文件中就写这些了,我们再到SecondViewController.m文件中再.m文件中,我们先实现.h中声明的方法- (void)returnText:(ReturnTextBlock)block { self.returnTextBlock = block;}这个方法是,把block赋值给我们新创建的,未实例化得returnTextBlock然后在视图将要消失的时候,我们把值传给第一个界面- (void)viewWillDisappear:(BOOL)animated { if (self.returnTextBlock != nil) { self.returnTextBlock(self.pa.text); }}第二个界面的工作,就这么完成了,我们转到第一个界面。
首先引用第二个界面然后把,textfild和button都映射到.m文件中,映射后的结果如图所示。然后我们实现跳转(button)的点击事件,- (IBAction)tiaozhuan:(UIButton *)sender { SecondViewController *sec = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] :@"a"]; [sec returnText:^(NSString *showText) { self.pass.text = showText; }]; [self.navigationController pushViewController:sec animated:YES];}在点击事件中添加 SecondViewController *sec = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] :@"a"]; [sec returnText:^(NSString *showText) { self.pass.text = showText; }]; [self.navigationController pushViewController:sec animated:YES]; SecondViewController *sec = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] :@"a"];这句话是获取SecondViewController。
[sec returnText:^(NSString *showText) { self.pass.text = showText; }];这句话是,调用方法returnText:并传值为^(NSString *showText) { self.pass.text = showText; }传的这个block,就赋值给了第二个界面的self.returnTextBlock。然后[self.navigationController pushViewController:sec animated:YES];跳转到第二个界面。
运行结果为。
转载请注明出处育才学习网 » iosblock怎么写