您的位置:首页 > 移动开发 > IOS开发

iOS-GCD多线程编程详解5

2015-01-10 15:41 531 查看
iOS-GCD多线程编程详解5

今天主要讲的函数是dispatch_once,该函数的作用是在程序生命周期范围内只执行提交的block一次,不会在执行第二次。

一.dispatch_once函数

void
dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);


参数:

1.predicate:该参数是为了表示该block执行完成或者已经执行,它必须是一个静态的long int 类型的变量

2.block:该block就是只执行一次的任务

使用:

static dispatch_once_t onceToken;

NSLog(@"前onceToken=%ld",onceToken);

dispatch_once(&onceToken, ^{
NSLog(@"中onceToken%ld",onceToken);
NSLog(@"dispatch_once ");
});

NSLog(@"后onceToken=%ld",onceToken);


运行结果:

2015-01-10 15:45:00.448 GCDTest[1006:55054]
onceToken=0
2015-01-10 15:45:00.449 GCDTest[1006:55054]
onceToken140734785690192
2015-01-10 15:45:00.449 GCDTest[1006:55054] dispatch_once
2015-01-10 15:45:00.449 GCDTest[1006:55054]
onceToken=-1

使用2:
static dispatch_once_t onceToken;

NSLog(@"前onceToken=%ld",onceToken);

dispatch_once(&onceToken, ^{
NSLog(@"中onceToken%ld",onceToken);
NSLog(@"dispatch_once ");
});

dispatch_once(&onceToken, ^{
NSLog(@"中onceToken%ld",onceToken);
NSLog(@"dispatch_once ");
});

dispatch_once(&onceToken, ^{
NSLog(@"中onceToken%ld",onceToken);
NSLog(@"dispatch_once ");
});

NSLog(@"后onceToken=%ld",onceToken);


运行结果:

2015-01-10 15:54:42.682 GCDTest[1047:58632]
onceToken=0
2015-01-10 15:54:42.683 GCDTest[1047:58632]
onceToken140734613617216
2015-01-10 15:54:42.683 GCDTest[1047:58632] dispatch_once
2015-01-10 15:54:42.683 GCDTest[1047:58632]
onceToken=-1

不管block被提交了多少次都只是被执行一次。onceToken的前后的值是0和-1,运行中为随机数,

使用3:
static dispatch_once_t onceToken;
static dispatch_once_t onceToken2;
static dispatch_once_t onceToken3;

NSLog(@"前onceToken=%ld",onceToken);
NSLog(@"前onceToken2=%ld",onceToken2);
NSLog(@"前onceToken3=%ld",onceToken3);

dispatch_once(&onceToken, ^{
NSLog(@"中onceToken%ld",onceToken);
NSLog(@"dispatch_once ");
});

dispatch_once(&onceToken2, ^{
NSLog(@"中onceToken2%ld",onceToken2);
NSLog(@"dispatch_once ");
});

dispatch_once(&onceToken3, ^{
NSLog(@"中onceToken3%ld",onceToken3);
NSLog(@"dispatch_once ");
});

NSLog(@"后onceToken=%ld",onceToken);
NSLog(@"后onceToken2=%ld",onceToken2);
NSLog(@"后onceToken3=%ld",onceToken3);


运行结果:

2015-01-10 15:58:26.562 GCDTest[1091:60066]
onceToken=0
2015-01-10 15:58:26.563 GCDTest[1091:60066]
onceToken2=0
2015-01-10 15:58:26.563 GCDTest[1091:60066]
onceToken3=0
2015-01-10 15:58:26.563 GCDTest[1091:60066]
onceToken140734702901808
2015-01-10 15:58:26.563 GCDTest[1091:60066] dispatch_once
2015-01-10 15:58:26.563 GCDTest[1091:60066]
onceToken2140734702901808
2015-01-10 15:58:26.563 GCDTest[1091:60066] dispatch_once
2015-01-10 15:58:26.563 GCDTest[1091:60066]
onceToken3140734702901808
2015-01-10 15:58:26.564 GCDTest[1091:60066] dispatch_once
2015-01-10 15:58:26.564 GCDTest[1091:60066]
onceToken=-1
2015-01-10 15:58:26.564 GCDTest[1091:60066]
onceToken2=-1
2015-01-10 15:58:26.564 GCDTest[1091:60066]
onceToken3=-1
从几种使用及其结果来看,只执行一次是有predicte参数来表示,为0表示未被执行,为-1表示执行了,被它表示的就不会被执行第二次。

二.实际编程中的应用
既然提交的block为在程序中只运行一次,那么如果你想那个类,对象,函数只被初始化一次只被实例化一次只被执行一次,你就可以把它包含到block中并通过该函数提交掉用。
在设计模式中单例模式是比较常用的,整个程序 中只有这类的一个静态实例变量,所以我们就可以通过该函数来实现一个单例的类。

1.新建一个类SingleObject
#import <Foundation/Foundation.h>

@interface SingleObject : NSObject
+(SingleObject *)shareObject;
@end


@implementation SingleObject
+(SingleObject *)shareObject{
static SingleObject *_share =nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
if (!_share) {
_share = [[SingleObject alloc]init];
}
});
return _share;
}
@end


单例的使用:
#import "ViewController.h"
#import "SingleObject.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

for (int i=0; i<5; i++) {
NSLog(@"第%d次---%@",i,[SingleObject shareObject]);
}

}
@end


运行结果分析:
1:

2015-01-10 16:11:09.336 GCDTest[1129:63127]
0次---<SingleObject: 0x7f8ce3737390>
2015-01-10 16:11:09.337 GCDTest[1129:63127]
1次---<SingleObject: 0x7f8ce3737390>
2015-01-10 16:11:09.338 GCDTest[1129:63127]
2次---<SingleObject: 0x7f8ce3737390>
2015-01-10 16:11:09.338 GCDTest[1129:63127]
3次---<SingleObject: 0x7f8ce3737390>
2015-01-10 16:11:09.338 GCDTest[1129:63127]
4次---<SingleObject: 0x7f8ce3737390>
2:

2015-01-10 16:13:55.572 GCDTest[1154:64460]
0次---<SingleObject: 0x7fff0bc61e80>
2015-01-10 16:13:55.573 GCDTest[1154:64460]
1次---<SingleObject: 0x7fff0bc61e80>
2015-01-10 16:13:55.573 GCDTest[1154:64460]
2次---<SingleObject: 0x7fff0bc61e80>
2015-01-10 16:13:55.573 GCDTest[1154:64460]
3次---<SingleObject: 0x7fff0bc61e80>
2015-01-10 16:13:55.573 GCDTest[1154:64460]
4次---<SingleObject: 0x7fff0bc61e80>
3:

2015-01-10 16:14:16.088 GCDTest[1162:64744]
0次---<SingleObject: 0x7fb1a04494b0>
2015-01-10 16:14:16.088 GCDTest[1162:64744]
1次---<SingleObject: 0x7fb1a04494b0>
2015-01-10 16:14:16.088 GCDTest[1162:64744]
2次---<SingleObject: 0x7fb1a04494b0>
2015-01-10 16:14:16.088 GCDTest[1162:64744]
3次---<SingleObject: 0x7fb1a04494b0>
2015-01-10 16:14:16.089 GCDTest[1162:64744]
4次---<SingleObject: 0x7fb1a04494b0>
几次运行的结果都是指向相同的一个对象。

小结读者可以根据自己的需求使用该函数,在程序中只使用一次。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: