线程间的通信
- 从子线程回到主线程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//执行耗时的异步操作
dispatch_async(dispatch_get_main_queue(), ^{
//回到主线程刷新UI
});
});
延时执行
- iOS常见的延时执行有两种方式
p 调用NSObject的方法
[self performSelector:@selector(run:) withObject:nil afterDelay:2.0];
p 使用GCD函数
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//2秒后异执行这里的代码
});
一次性代码
- 使用dispatch_once函数能保证某段代码在执行过程中只被执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//只执行一次的代码(这里默认是线程安全的)
});
dispatch_barrier_async (栅栏函数)
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
dispatch_barrier_async的作用是在并行队列中,插入其中,就会有等到其前面的线程执行完毕,然后执行自己的线程,再执行其后面的线程。起到一个栅栏的作用
示例代码
- (void)barrier
{
dispatch_queue_t queue = dispatch_queue_create("12312312", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"----1-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"----2-----%@", [NSThread currentThread]);
});
dispatch_barrier_async(queue, ^{
NSLog(@"----barrier-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"----3-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"----4-----%@", [NSThread currentThread]);
});
}
dispatch_apply()
- 方法
void
dispatch_apply(size_t iterations, dispatch_queue_t queue,
void (^block)(size_t));
- 参数
iterations 执行的次数
queue 提交到的队列
block 执行的任务
size_t 传当前索引
功能
p 把一项任务提交到队列中多次执行,具体是并行执行还是串行执行由队列本身决定.注意,dispatch_apply不会立刻返回,在执行完毕后才会返回,是同步的调用。
p 它可以起到快速迭代的作用,类似于for循环的遍历,但for循环的遍历是一个一个执行的,而dispatch_apply是几乎同时执行的示例代码
/**
* 快速迭代
*/
- (void)apply
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSString *from = @"/Users/shenzhouguangda/Desktop/icon";
NSString *to = @"/Users/shenzhouguangda/Desktop/icon1";
NSFileManager *mgr = [NSFileManager defaultManager];
NSArray *subpaths = [mgr subpathsAtPath:from];
dispatch_apply(subpaths.count, queue, ^(size_t index) {
NSString *subpath = subpaths[index];
NSString *fromFullpath = [from stringByAppendingPathComponent:subpath];
NSString *toFullpath = [to stringByAppendingPathComponent:subpath];
// 剪切
[mgr moveItemAtPath:fromFullpath toPath:toFullpath error:nil];
NSLog(@"%@---%@", [NSThread currentThread], subpath);
});
}
队列组
有这么一种需求
p 首先:分别异步执行两个耗时操作
p 其次:等两个异步操作都执行完毕后,再回到主线程执行操作如果想要快速高效的实现上述需求,可以考虑用队列组
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//执行一个耗时操作
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//执行一个耗时操作
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//等到前面的异步操作都执行完毕后,回到主线程。
});
单例模式(GCD)
单例模式的作用
p 可以保证在程序运行过程中,一个类只有一个实例,而且该实例易于外界访问
p 从而方便的控制了实例个数,并节约系统资源单例模式的适用场合
p 在整个应用程序中,共享一份资源(这份资源只要创建初始化一次)
p 单例模式在ARC和MRC环境下的写法不同,需要编写俩套不同的代码
p 可以用宏判断是否为ARC环境
#if __has_feature(objc_arc)
// ARC
#else
// MRC
#endif
- 利用GCD的 dispatch_once 可以创建单例类
- 示例代码
//.h文件
#import <Foundation/Foundation.h>
@interface LGJPerson : NSObject
/** 名字 */
@property (nonatomic, strong) NSString *name;
+ (instancetype)sharedPerson;
@end
//.m文件
#import "LGJPerson.h"
@interface LGJPerson() <NSCopying>
@end
@implementation LGJPerson
static LGJPerson *_person;
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [super allocWithZone:zone];
});
return _person;
}
+ (instancetype)sharedPerson
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [[self alloc] init];
});
return _person;
}
- (id)copyWithZone:(NSZone *)zone
{
return _person;
}
@end
- 单例模式可以抽成一个宏,可以更加快速的创建单利类
p 示例代码(\ 代表下一行也是宏的内容 ## 是连接符)
// .h文件
#define LGJSingletonH(name) + (instancetype)shared##name;
// .m文件
#define LGJSingletonM(name) \
static id _instance; \
\
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
非GCD创建单例模式
- ARC中,单例模式的实现
p 在.m中保留一个全局的static的实例
static id _instance;
//重写allocWithZone:方法,在这里创建唯一的实例(注意线程安 全)
+ (id)allocWithZone:(struct _NSZone *)zone
{
@synchronized(self) {
if (!_instance) {
_instance = [super allocWithZone:zone];
}
}
return _instance;
}
p提供1个类方法让外界访问唯一的实例
+ (instancetype)sharedSoundTool
{
@synchronized(self) {
if (!_instance) {
_instance = [[self alloc] init];
}
}
return _instance;
}
实现copyWithZone:方法
- (id)copyWithZone:(struct _NSZone *)zone
{
return _instance;
}
- 非ARC中(MRC),单例模式的实现(比ARC多了几个步骤)
p 实现内存管理方法
- (id)retain { return self; }
- (NSUInteger)retainCount { return 1; }
- (oneway void)release {}
- (id)autorelease { return self; }