月度归档:2018年11月

使用GCD封装一个简单的定时器

1、GCD定时器实现的基础代码

1
2
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, );
dispatch_source_set_timer(timer, DISPATCH_TIME[......]<p class="read-more"><a href="https://www.yusian.com/blog/project/2018/11/30/1106431446.html">继续阅读</a></p>

定时器NSTimer、CADisplayLink及代理NSProxy的基本使用

1、NSTimer常用的两种方式:scheduled与使用Runloop addTimer

1
2
[NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
    NSLo[......]<p class="read-more"><a href="https://www.yusian.com/blog/project/2018/11/29/1742151443.html">继续阅读</a></p>

文件读写操作中锁的使用

1、简述
1.1、多线程操作中必然会涉及到锁的概念,使用锁来确保线程安全;
1.2、事实上某些操作,比如数据读取是可以允许多线程同时操作的;
1.3、但写操作不行,数据写入动作必须是同步的,否则会出现数据错误;
1.4、如果读、写操作动作同时发生,并且多线程并发操作时该如何处理?
1.5、通过普通加锁实现线程同步,这样线程是安全了,但影响了读取的效率;
1.6、基本思路是
1.6.1、允许读取操作多线程并发进行;
1.6.2、写入操作只能单个线程同步进行;
1.7、常用的解决方案有两个
1.7.1、pthread_rwlock
1.7.2、dispatch_barrier_async

2、代码示例
2.1、pthread_rwlock[……]

继续阅读

GCD同步任务实现加锁效果

1、DISPATCH_QUEUE_SERIAL
1.1、串行队列使队列中的任务同步执行,单次只能执行一个任务
1.2、示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#import "ViewController.h"
#import <pthread.h>
@implementation ViewController
static NSUInteger ticketCount_ = 20;
- (void)viewDidLoad
{
    [super viewDidLoad];
    dispatch_queue_t queue = dispatch_queue_create("com.yusian.custom-queue", DISPATCH_QUEUE_SERIAL);
    for (int i = 0; i < 5; i++) {
        dispatch_async(queue, ^{
            [self saleTicket];
        });
    }
}
- (void)saleTicket
{
    NSUInteger remain = ticketCount_;
    sleep(1);
    ticketCount_ = --remain;
    NSLog(@"%ld, %@", ticketCount_, [NSThread currentThread]);
}
@end

执行结果:[……]

继续阅读

基于pthread_mutex封装的锁NSLock、NSCondition、NSConditionLock、NSRecursiveLock、@Synchronized

参考链接:iOS多线程中的几种加锁类型OSSpinLock、os_unfair_lock、pthread_mutex

1、pthread_mutex是c语言实现的跨平台互斥锁,应该是一种主流锁吧,OC多种形态的锁都是基于pthread_mutex,常见的有NSLock、NSCondition、NSConditionLock、NSRecursiveLock、@Synchronized

2、各种锁的基本使用
2.1、NSLock

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#import "ViewController.h"
#import <pthread.h>
 
@interface ViewController ()
{
    NSLock           *_lock;
}
@end
 
@implementation ViewController
static NSUInteger ticketCount = 20;
- (void)viewDidLoad
{
    [super viewDidLoad];
    _lock = [[NSLock alloc] init];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        for (int i = 0; i < 5; i++) {
            [self saleTickte];
        }
    });
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        for (int i = 0; i < 5; i++) {
            [self saleTickte];
        }
    });
}
 
- (void)saleTickte
{
    [_lock lock];
    // lockBeforeDate:方法能在指定时间后自动解锁
    // [_lock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:3]];
    NSUInteger remain = ticketCount;
    sleep(0.5);
    ticketCount = --remain;
    NSLog(@"%ld-%@", ticketCount, [NSThread currentThread]);
    [_lock unlock];
}
@end

输出结果:[……]

继续阅读