四、单例模式(懒汉式)
1.ARC
@interface HMDataTool : NSObject
+ (instancetype)sharedDataTool;
@end
@implementation HMDataTool
// 用来保存唯一的单例对象
static id _instace;
+ (id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super allocWithZone:zone];
});
return _instace;
}
+ (instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self alloc] init];
});
return _instace;
}
- (id)copyWithZone:(NSZone *)zone
{
return _instace;
}
@end
2.非ARC
@interface HMDataTool : NSObject
+ (instancetype)sharedDataTool;
@end
@implementation HMDataTool
// 用来保存唯一的单例对象
static id _instace;
+ (id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super allocWithZone:zone];
});
return _instace;
}
+ (instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self alloc] init];
});
return _instace;
}
- (id)copyWithZone:(NSZone *)zone
{
return _instace;
}
- (oneway void)release {
}
- (id)retain {
return self;
}
- (NSUInteger)retainCount {
return 1;
}
- (id)autorelease {
return self;
}
@end
五、NSOperation和NSOperationQueue
1.队列的类型
1> 主队列
* [NSOperationQueue mainQueue]
* 添加到"主队列"中的操作,都会放到主线程中执行
2> 非主队列
* [[NSOperationQueue alloc] init]
* 添加到"非主队列"中的操作,都会放到子线程中执行
2.队列添加任务
* - (void)addOperation:(NSOperation *)op;
* - (void)addOperationWithBlock:(void (^)(void))block;
3.常见用法
1> 设置最大并发数
- (NSInteger)maxConcurrentOperationCount;
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
2> 队列的其他操作
* 取消所有的操作
- (void)cancelAllOperations;
* 暂停所有的操作
[queue setSuspended:YES];
* 恢复所有的操作
[queue setSuspended:NO];
4.操作之间的依赖(面试题)
* NSOperation之间可以设置依赖来保证执行顺序
* [operationB addDependency:operationA];
// 操作B依赖于操作A,等操作A执行完毕后,才会执行操作B
* 注意:不能相互依赖,比如A依赖B,B依赖A
* 可以在不同queue的NSOperation之间创建依赖关系
5.线程之间的通信
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
// 1.执行一些比较耗时的操作
// 2.回到主线程
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
}];
}];
六、从其他线程回到主线程的方式
1.perform...
[self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
2.GCD
dispatch_async(dispatch_get_main_queue(), ^{
});
3.NSOperationQueue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
}];
七、判断编译器的环境:ARC还是MRC?
#if __has_feature(objc_arc)
// 当前的编译器环境是ARC
#else
// 当前的编译器环境是MRC
#endif
八、类的初始化方法
1.+(void)load
* 当某个类第一次装载到OC运行时系统(内存)时,就会调用
* 程序一启动就会调用
* 程序运行过程中,只会调用1次
2.+(void)initialize
* 当某个类第一次被使用时(比如调用了类的某个方法),就会调用
* 并非程序一启动就会调用
3.在程序运行过程中:1个类中的某个操作,只想执行1次,那么这个操作放到+(void)load方法中最合适
九、第三方框架的使用建议
1.用第三方框架的目的
1> 开发效率:快速开发,人家封装好的一行代码顶自己写的N行
2> 为了使用这个功能最牛逼的实现
2.第三方框架过多,很多坏处(忽略不计)
1> 管理、升级、更新
2> 第三方框架有BUG,等待作者解决
3> 第三方框架的作者不幸去世、停止更新(潜在的BUG无人解决)
4> 感觉:自己好水
3.比如
流媒体:播放在线视频、音频(边下载边播放)
非常了解音频、视频文件的格式
每一种视频都有自己的解码方式(C\C++)
4.总结
1> 站在巨人的肩膀上编程
2> 没有关系,使劲用那么比较稳定的第三方框架
宏定义头文件 HMSingleton.h
// .h文件
#define HMSingletonH(name) + (instancetype)shared##name;
// .m文件
#if __has_feature(objc_arc)
#define HMSingletonM(name) \
static id _instace; \
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [super allocWithZone:zone]; \
}); \
return _instace; \
} \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [[self alloc] init]; \
}); \
return _instace; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instace; \
}
#else
#define HMSingletonM(name) \
static id _instace; \
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [super allocWithZone:zone]; \
}); \
return _instace; \
} \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [[self alloc] init]; \
}); \
return _instace; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instace; \
} \
\
- (oneway void)release { } \
- (id)retain { return self; } \
- (NSUInteger)retainCount { return 1;} \
- (id)autorelease { return self;}
#endif
本文详细介绍了单例模式的懒汉式实现方式,并对比了ARC和非ARC环境下单例模式的区别。同时,文章还探讨了NSOperation和NSOperationQueue在多线程场景下的应用,包括如何设置最大并发数、添加任务、设置依赖以及线程间的通信。最后,文章提供了从其他线程回到主线程的方式,以及如何通过宏定义头文件来简化单例模式的实现过程。
1754

被折叠的 条评论
为什么被折叠?



