iOS-GCD多线程编程详解5

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>

几次运行的结果都是指向相同的一个对象。



小结读者可以根据自己的需求使用该函数,在程序中只使用一次。


转载于:https://www.cnblogs.com/fanyiyao-980404514/p/4227546.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值