标签:number return result 编译器 c语言
代码块对象:
通常称:代码块,是对C语言的扩展,,除了函数中的代码,其害包含变量绑定。代码块有时也被称为闭包(closure)。两种绑定类型:自动型和托管型。自动型使用的是栈中的内存,而托管绑定是通过堆创建的。
代码块和函数指针:
代码块特征:1.返回类型可以手动声明也可以由编译器推导。2.具有指定类型的参数列表。3.有用名称。
声明一个函数指针:void(*my_func)(void); 这是很基础的函数指针,它没有参数和返回结果,只要把 * 替换成 ^ 就可以把它转换成一个代码块的定义了。如:void (^my_block)(void);
在声明代码块变量和代码块实现的开头位置都要使用幂操作符。与函数中一样代码块都要放在{}中。
int (^square_block)(int number) = ^(int number) { return ( number * number);};
int result = square_block(5); printf(“Result = %d \n”,result);
这个特别的代码块获取了一个整形参数并返回了这个数字的平方,等号前面是代码块的定义,而等号后面是实现内容。
通用表达式:<returntype> (^blockname)(list of arguments) = ^(arguments){ body; };
typdef
typedf double (^MKSampleMultiply2BlockRef)(double c, double d);
这行代码定义了一个名为MKSampleMultiply2BlockRef的代码块变量,它包含两个双浮点型参数并返回一个双浮点型数值。
MKSampleMultiply2BlockRef multiply2 =^(double c, double d) {return c * d ; };
printf(“%f , %f “,multply2(4,5),multply2(5, 2));
本地变量
本地变量就是和代码块在同一范围内声明的变量。
typedef double (^MKSample) (void);
double a = 10 , b = 20;//本地变量
MKSample multiply = ^(){ return a * b;};
NSLog(@"%f",multiply());//结果是200
a = 20; b = 50;
NSLog(@"%f",multiply());//结果仍然是200
参数变量
代码块中的参数变量与函数中的参数变量具有相同的作用。
_block变量
本地常量会被代码块作为常量获取到,如果想修改它们的值就必须将其声明为可修改的,例如: double c = 3; MKSample multiply = ^(double a,double b){ return a * b;}; 此时编译器将报错。 应该将c声明为 _block double c =3;
_block类型的两个限制:没有长度可变的数组,没有包含可变长度数组的结构体。这两种变量不能声明为 _block 类型。
代码块内部的本地变量
这些变量与函数中的本地变量具有相同的作用。
Objective-C变量
如果引用了一个OC对象,必须要保留它;如果通过引用访问了一个实例变量,要保留一次self(执行方法对象);通过数值访问了一个实例变量,变量需要保留。
因为代码块是对象,所以可以向他发送任何与内存管理有关的消息。在C语言级别中必须使用Block_copy()和Block_release()函数来适当管理内存。
并发性:
如果只想让一些代码在后台运行,nsobject提供了方法,这些方法名字中都有performSelector:,最简单的就是:performSelectorInBackground:withObject:;他能在后台执行一个方法,它通过创建一个进程来运行方法。
这些方法不能有返回值,并且要么没有参数,要么只有一个参数对象。只能使用以下代码格式的一种:
-(void)myMethod; -(void)myMethod:(id)myObject;
我们应该实现的代码如下:
-(void) myBackgroudMethod{
@autoreleasepool
{
NSLog(@“My Background Method.");
}
} 或者:
-(void) myBackgroudMethod: (id)myObject{
@autoreleasepool
{
NSLog(@“My Background Method.");
}
}
如果想要在后台执行你的方法,只需调用performSelectorInBackground:withObject:;如下:
[self performSelectorInBackground:@selector(myBackgroudMethod)withObject:nil];
调度队列:
连续队列:dispatch_queue_t my_serial_queue;
my_serial_queue = dispatch_queue_create (“compares.MySerialQueue1”,NULL);
第一个参数是队列的名称,第二个是负责提供队列的特性,现在用不到所以是null。
如果要更改优先级,可以调用dispatch_get_global_queue方法。
三种优先级:DISPATCH_QUEUE_PRIORITY_HIGH
DISPATCH_QUEUE_PRIORITY_LOW
DISPATCH_QUEUE_PRIORITY_DEFALUT.
使用dispatch_get_main_queue可以访问与应用程序主线程相关的连续队列。
调度队列是引用计数对象,可以用dispatch_retain()和dispatch_release()来修改计数器的值。
关于清理函数:让对象在弃用它的时候调用一个函数,就像类中的dealloc函数。
void function_name(void *context);
void myFinalizer(viod *content){
NSLog(@“myFinalizerFunction.”);
NSMutableDictionary *theData = (__bridge_transfer NSMutableDictionary* )context;
[theData removeAllObjects];
}//该函数又叫终结器函数
__bridge_transfer关键字是把对象的内存管理由全局释放池变换成了我们的函数。
__bridge关键字是告诉ARC我们自己不管理上下文内容,交给系统来管理。
调度程序:
添加任务的最简单的方法是通过代码块,代码块必须是dispatch_block_t这样的类型,要定义为没有参数和返回值可行。 例如:typedef void (^dispatch_block_t)(void).
先添加异步代码块,这个函数有两个参数:队列和代码块。
dispatch_async(_serial_queue,^{ NSLog(@“Serial Task 1”) ; } );
如果要同步添加,使用dispatch_sync函数。函数原型:void function_name (void *argument)
等后续~~~~~~~~~
最近课程上的进度加快了很多,加之基础太弱,学起来很是吃力///
标签:number return result 编译器 c语言
原文地址:http://wenran.blog.51cto.com/9428559/1679416