当前位置:首页 » 编程软件 » iosblock在什么时候编译

iosblock在什么时候编译

发布时间: 2025-05-24 11:30:17

‘壹’ 如何在iOS中使用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 sortArrayUsingComparator: 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 enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
if ([obj :string] == NSOrderedSame) {
*stop = YES;
found = YES;
}
}];
掌握它需要一点时间,但一旦领会了还是很简答的,是不?我建议大家看下Apple的文档,并看看其中引用到的一些API以确认下它们是如何使用的。多练习,熟能生巧!

‘贰’ arc是一种编译时特性还是运行时特性

ARC本质 ARC编译器()特性运行特性更垃圾收器(GC) Automatic Reference Counting (ARC) is a compiler-level feature that simplifies the process of managing object lifetimes (memory management) in Cocoa applications. ARC相于MRC(Manual Reference Counting或称非ARC文我直使用MRC指代非ARC管理式)改进前技术本质没区别具体信息参考ARC编译器官文档 ARC启与关闭 同于XCode四创建工程选择关闭ARCXCode5创建工程默认启ARC没关闭ARC选项 需要特定文件启或关闭ARC工程选项选择Targets -> Compile Phases -> Compile Sources面找应文件添加flag: 打ARC:-fobjc-arc 关闭ARC:-fno-objc-arc 图: ARC修饰符 ARC主要提供四种修饰符别:__strong,__weak,__autoreleasing,__unsafe_unretained __strong 表示引用强引用应定义property"strong"所象没任何强引用指向才释放 注意:声明引用加修饰符引用默认强引用需要释放强引用指向象需要强引用置nil __weak 表示引用弱引用应定义property用"weak"弱引用影响象释放即要象没任何强引用指向即使依00弱引用象指向没用该象依释放象释放同指向弱引用自置nil技术叫zeroing weak pointer效防止效指针、野指针产__weak般用delegate关系防止循环引用或者用修饰指向由Interface Builder编辑与UI控件 __autoreleasing 表示autorelease pool自释放象引用MRC代autorelease用相同定义property能使用修饰符任何象property都应该autorelease型 见误解ARC没autorelease自释放看起像点余误解能源自于ARC自autorelease自混淆其实要看每iOS Appmain.m文件能知道autorelease仅存着并且变更fashion:需要再手工创建需要再显式调用[drain]释放内存池 两行代码意义相同 NSString *str = [[[NSString alloc] initWithFormat:@"hehe"] autorelease]; // MRC NSString *__autoreleasing str = [[NSString alloc] initWithFormat:@"hehe"]; // ARC 关于autoreleasepool做展详细信息参考官文档或者其文章 __autoreleasingARC主要用参数传递返值(out-parameters)引用传递参数(pass-by-reference)情况 __autoreleasing is used to denote arguments that are passed by reference (id *) and are autoreleased on return. 比用NSError使用: NSError *__autoreleasing error; if (![data writeToFile:filename options:NSDataWritingAtomic error:&error]) { NSLog(@"Error: %@", error); } (面writeToFileerror参数类型(NSError *__autoreleasing *)) 注意error定义strong型编译器帮隐式做事情保证终传入函数参数依__autoreleasing类型引用 NSError *error; NSError *__autoreleasing tempError = error; // 编译器添加 if (![data writeToFile:filename options:NSDataWritingAtomic error:&tempError]) { error = tempError; // 编译器添加 NSLog(@"Error: %@", error); } 所提高效率避免种情况我般定义error候其(实实==)声明__autoreleasing类型: NSError *__autoreleasing error; 加__autoreleasing相于MRC返值error做事情: *error = [[[NSError alloc] init] autorelease]; *error指向象创建放入autoreleasing pool等待使用结束自释放函数外error使用者并需要关*error指向象释放 另外点ARC所种指针指针 (NSError **)函数参数加修饰符编译器默认认定__autoreleasing类型 比面两段代码等同: - (NSString *)doSomething:(NSNumber **)value { // do something } - (NSString *)doSomething:(NSNumber * __autoreleasing *)value { // do something } 除非显式给value声明__strong否则value默认__autoreleasing 点某些类隐式使用自autorelease pool种候使用__autoreleasing类型要特别 比NSDictionary[]: - (void)loopThroughDictionary:(NSDictionary *)dict error:(NSError **)error { [dict :^(id key, id obj, BOOL *stop){ // do stuff if (there is some error && error != nil) { *error = [NSError errorWithDomain:@"MyError" code:依 userInfo:nil]; } }]; } 隐式创建autorelease pool面代码实际类似于: - (void)loopThroughDictionary:(NSDictionary *)dict error:(NSError **)error { [dict :^(id key, id obj, BOOL *stop){ @autoreleasepool // 隐式创建 { if (there is some error && error != nil) { *error = [NSError errorWithDomain:@"MyError" code:依 userInfo:nil]; } } }]; // *error 已经dict做枚举遍历创建autorelease pool释放掉 :( } 能够使用*error我需要strong型临引用dict枚举Block用临引用保证引用指向象dict枚举Block释放确式: - (void)loopThroughDictionary:(NSDictionary *)dict error:(NSError **)error { __block NSError* tempError; // 加__block保证Block内修改 [dict :^(id key, id obj, BOOL *stop) { if (there is some error) { *tempError = [NSError errorWithDomain:@"MyError" code:依 userInfo:nil]; } }] if (error != nil) { *error = tempError; }

‘叁’ 如何在iOS中使用Block──How to use Blocks with iOS

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 sortArrayUsingComparator: 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 enumerateObjectsUsingBlock:^(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.

热点内容
php且 发布:2025-05-24 15:14:28 浏览:857
图割点算法 发布:2025-05-24 15:10:31 浏览:121
云服务器学习 发布:2025-05-24 15:08:40 浏览:746
1linux 发布:2025-05-24 15:08:39 浏览:459
安卓用什么管理软件连接电脑 发布:2025-05-24 14:57:27 浏览:398
android解析复杂json 发布:2025-05-24 14:55:17 浏览:343
c语言跟c的区别 发布:2025-05-24 14:46:29 浏览:887
python源码分析 发布:2025-05-24 14:41:31 浏览:594
吉利帝豪2021配置如何 发布:2025-05-24 14:33:42 浏览:516
服务器怎么改变休眠 发布:2025-05-24 14:29:14 浏览:485