首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 操作系统 >

IOS 应用Block

2012-07-30 
IOS 使用Block调用Block如果把block声明为变量,你可以将block作为函数来使用。下面用两个例子来说明:int (^

IOS 使用Block

调用Block

如果把block声明为变量,你可以将block作为函数来使用。下面用两个例子来说明:

int (^oneFrom)(int) = ^(int anInt) {

    return anInt - 1;

};


printf("1 from 10 is %d", oneFrom(10));

// Prints "1 from 10 is 9"


float (^distanceTraveled) (float, float, float) =

^(float startingSpeed, float acceleration, float time) {

    

    float distance = (startingSpeed * time) + (0.5 * acceleration * time * time);

    return distance;

};


float howFar = distanceTraveled(0.0, 9.8, 1.0);

// howFar = 4.9

当你经常传递一个block作为函数或者方法的参数时,其实是将block当成了inline。

你可以将一个block当成任何其他的参数一样,作为一个函数参数传递给函数。然而在大部分情况下,你不需要声明blocks,而只是在blocks需要当成参数时,直接内联实现他们。下面是一个使用qsort_b的的例子,其中qsort_b与标准的qsort_r函数类似,但是把一个block当成它的最后一个参数。

char *myCharacters[3] = { "TomJohn", "George", "Charles Condomine" };


qsort_b(myCharacters, 3, sizeof(char *), ^(const void *l, const void *r) {

    char *left = *(char **)l;

    char *right = *(char **)r;

    return strncmp(left, right, 1);

});

// Block implementation ends at "}"


// myCharacters is now { "Charles Condomine", "George", "TomJohn" }

注意到函数的参数列表中包含有一个block。下面的例子显示在dispatch_apply函数中使用block。dispatch_apply声明如下:

void dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t));

该函数为了实现多种调用而采用一个dispatch队列。函数包含3个参数:第一个指定运行的迭代器的数量;第二个指定提交的block对应的队列;第三个就是block本身,该block将依次取出迭代器当前index对应的一个参数。

你可以使用dispatch_apply简单的打印出迭代器的index,具体代码为:

#include <dispatch/dispatch.h>

size_t count = 10;

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);


dispatch_apply(count, queue, ^(size_t i) {

    printf("%u\n", i);

});

将Block当成方法的参数

Cocoa可以在很多的方法中使用blocks。你可以将block作为方法参数传递给方法。

下面的例子表示决定出现在给定filter集的一个数组的元素是否是属于前五个成员。

NSArray *array = [NSArray arrayWithObjects: @"A", @"B", @"C", @"A", @"B", @"Z",@"G", @"are", @"Q", nil];

NSSet *filterSet = [NSSet setWithObjects: @"A", @"Z", @"Q", nil];


BOOL (^test)(id obj, NSUInteger idx, BOOL *stop);


test = ^ (id obj, NSUInteger idx, BOOL *stop) {

    

    if (idx < 5) {

        if ([filterSet containsObject: obj]) {

            return YES;

        }

    }

    return NO;

};


NSIndexSet *indexes = [array indexesOfObjectsPassingTest:test];


NSLog(@"indexes: %@", indexes);


/*

 Output:

 indexes: <NSIndexSet: 0x10236f0>[number of indexes: 2 (in 2 ranges), indexes: (0 3)]

 */

下面的例子决定一个NSSet对象是否包含了指定一个局部变量的单词,如果包含了,那么设置另外一个局部变量(found)为YES。注意到found同样声明为__block变量,而且该block定义为内联。

__block BOOL found = NO;

NSSet *aSet = [NSSet setWithObjects: @"Alpha", @"Beta", @"Gamma", @"X", nil];

NSString *string = @"gamma";


[aSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {

    if ([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame) {

        *stop = YES;

        found = YES;

    }

}];


// At this point, found == YES

一般来说,你不需要复制或者保留block。当你希望使用block时,你只需要在声明block之后的作用域中,复制一份。复制将把block移动到内存堆中。可以使用下面的两个C函数来复制或者释放block。

Block_copy();

Block_release();

如果使用Objective-C,你可以给block发送copy、retain,以及 release (包含 autorelease) 消息。

为了避免内存泄露,除非在自动垃圾回收环境,你必须总是在使用Block_copy()之后使用Block_release()。也必须在使用了copy或retain之后使用release(或autorelease)。

必须避免的一些模式:

blcok语法(^{ ... })是一种局部栈数据结构的地址,用来代表block。这种局部栈数据结构的作用域是一个闭合的语句中,因此必须避免使用下面的模式:

void dontDoThis() {

    void (^blockArray[3])(void);  // an array of 3 block references

    

    for (int i = 0; i < 3; ++i) {

        blockArray[i] = ^{ printf("hello, %d\n", i); };

        // WRONG: The block literal scope is the "for" loop

    }

}


void dontDoThisEither() {

    void (^block)(void);

    

    int i = random();

    if (i > 1000) {

        block = ^{ printf("got i at: %d\n", i); };

        // WRONG: The block literal scope is the "then" clause

    }

    // ...

}

调试:

你可以在block中添加断电来进行单步调试,也可以通过使用invoke-block在GDB会话中调用block,如下面的例子:

$ invoke-block myBlock 10 20

如果需要传递一个C类型的string,你必须应用它。例如,给doSomethingWithString传递this string,你必须这么写:

$ invoke-block doSomethingWithString "\"this string\""


PS:原文地址http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/bxUsing.html

     还可以参考Using Blocks in iOS 4: Designing with Blocks

热点排行