代码块和并发性

代码块对象:

通常称:代码块,是对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)

等后续~~~~~~~~~



最近课程上的进度加快了很多,加之基础太弱,学起来很是吃力///

时间: 2024-08-21 16:03:24

代码块和并发性的相关文章

代码块与并发性

1.代码块 代码块对象(通常称为代码块)是对C语言中函数的扩展.除了函数中的代码,代码块还包含变量绑定.代码块有时也称为闭包(closure). 代码块包含两种类型的绑定:自动型和托管型.自动绑定(automatic binding)使用的是栈中的内存,而托管绑定(managed binding)是通过堆创建的. 1.1 代码块定义和实现 代码块借鉴了函数指针的语法.与函数指针相似,代码块具有以下特征: 返回类型可以手动声明,也可以由编译器推导: 具有指定类型的参数列表 拥有名称 代码: int

Objective-c 05 类别 类扩展 委托 非正式协议 协议 代码块 并发性 队列

类别 为已经存在的类添加行为时,通常采用创建子类的方法,不过有时子类并不方便, 比如:创建NSString的子类,但是NSString实际上只是一个类簇的表面形式.因而为这样的类创建子类会非常困难.在其他情况下, 也许可以创建它的子类,但是用到的工具集和库无法帮你处理新类的对象的.例如:当使用stringWithFormat:类方法生成新字符串时,你创建的 NSString类的新子类就无法返回.   利用Objective-C的动态运行时分配机制,可以为现有的类添加新的方法.这些新的方法在Obj

编码最小单位:代码块。

代码块:完成一定功能的一系列的代码 ,或者是几行代码 或者是 连续调用几个函数. 将代码分割成代码块,或者通过分割成单独的函数 又或者 仅是录入几行空白部分实现. 在完成一定功能的代码块中最好不要加入其他功能的代码 且  要注意代码块的顺序性   尤其是在代码块间存在着数据共享. 上文源于实际开发中.且代码排查花费了12人时. 伪代码举例: ①.存在TimerManager类,其属性有List<ActionTimer> list.方法有removeTimer(id:String).run():

用亲身经历告诉你,在你的并发程序代码块中,最好最好不要有引用类型

用亲身经历告诉你,在你的并发程序代码块中,最好最好不要有引用类型,必要的string类型还是可以的.目前正在把自己前段时间写的并发程序放到自己的项目中,以提高速度,由于我的项目是与移动对接的,因此,询问了移动的接口能不能响应高并发之后,并且得到了肯定的答复,我就开始着手demo设计了,但是一直出错,一直有问题,后来想到,可能是引用类型的问题,因为我的并发代码需要不断地给一个类实例对象的某个字段赋值,然后去调用移动接口,我就捉摸着,可能是因为并发太快了,然后这个引用类型赋值的之后,没有来的及更换内

并发编程(5):锁对象、同步代码块

1.同步代码块 使用synchronized声明的方法在某些情况下是有弊端的,比如A线程调用同步的方法执行一个很长时间的任务,那么B线程就必须等待比较长的时间才能执行,这样的情况下可以使用synchronized代码块去优化代码执行时间,也就是通常所说的减小锁的粒度. 代码 public class Demo7 { public void doLongTimeTask(){ try { System.out.println("当前线程开始:" + Thread.currentThrea

Java并发学习之十四——使用Lock同步代码块

本文是学习网络上的文章时的总结,感谢大家无私的分享. Java提供另外的机制用来同步代码块.它比synchronized关键字更加强大.灵活.Lock 接口比synchronized关键字提供更多额外的功能.在使用Lock时需要注意的是要释放Lock锁. package chapter2; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /* * 打印队列 */ pu

深入了解 Scala 并发性

2003 年,Herb Sutter 在他的文章 “The Free Lunch Is Over” 中揭露了行业中最不可告人的一个小秘密,他明确论证了处理器在速度上的发展已经走到了尽头,并且将由全新的单芯片上的并行 “内核”(虚拟 CPU)所取代.这一发现对编程社区造成了不小的冲击,因为正确创建线程安全的代码,在理论而非实践中,始终会提高高性能开发人员的身价,而让各公司难以聘用他们.看上去,仅有少数人充分理解了 Java 的线程模型.并发 API 以及 “同步” 的含义,以便能够编写同时提供安全

JVM 并发性: Java 和 Scala 并发性基础

处理器速度数十年来一直持续快速发展,并在世纪交替之际走到了终点.从那时起,处理器制造商更多地是通过增加核心来提高芯片性能,而不再通过增加时钟速率来提高芯片性能.多核系统现在成为了从手机到企业服务器等所有设备的标准,而这种趋势可能继续并有所加速.开发人员越来越需要在他们的应用程序代码中支持多个核心,这样才能满足性能需求. 在本系列文章中,您将了解一些针对 Java 和 Scala 语言的并发编程的新方法,包括 Java 如何将 Scala 和其他基于 JVM 的语言中已经探索出来的理念结合在一起.

JVM 并发性: 阻塞还是不阻塞?

在任何并发性应用程序中,异步事件处理都至关重要.事件来源可能是不同的计算任务.I/O 操作或与外部系统的交互.无论来源是什么,应用程序代码都必须跟踪事件,协调为响应事件而采取的操作.Java 应用程序可采用两种基本的异步事件处理方法:该应用程序有一个协调线程等待事件,然后采取操作,或者事件可在完成时直接执行某项操作(通常采取执行应用程序所提供的代码的方式).让线程等待事件的方法被称为阻塞 方法.让事件执行操作.线程无需显式等待事件的方法被称为非阻塞 方法. 旧的 java.util.concur