1. OC中
1.1 NetworkTool.h 文件
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
应用场景: 场景工具,音频工具
*/
@interface NetworkTools : NSObject
/// 单例的全局访问点 + 表示类函数
+(instancetype)sharedTools;
@end
NS_ASSUME_NONNULL_END
1.2 NetworkTool.m 文件
#import "NetworkTools.h"
@implementation NetworkTools
+(instancetype)sharedTools{
static id instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc]init];
});
return instance;
}
@end
1.3 调用
#import "ViewController.h"
#import "NetworkTools.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%@",[NetworkTools sharedTools]);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"%@",[NetworkTools sharedTools]);
}
@end
2. Swift 中
1. 创建 SoundTools 文件
class SoundTools: NSObject {
override init() {
print("sharedTools2")
super.init()
}
//静态区的对象只能设置一次数值
@objc static let sharedTools2 = SoundTools()
//Swift 中的单例写法和懒加载几乎一样 ‘static let’
//同样也是在第一次使用时,才会创建对象
static let sharedTools3: SoundTools = {
print("sharedTools3")
return SoundTools()
}()
//以下代码是仿 OC 的写法
//在 Swift 中不允许在函数中定义静态成员
private static var instance: SoundTools?
private static let onceToken = NSUUID().uuidString
//1.提供全局的访问点
class func sharedTools() -> SoundTools{
DispatchQueue.once {
instance = SoundTools()
}
return instance!
}
}
2.2 DispatchQueue.once 以弃用,自定义扩展类 DispatchQueue+Extension.swift
import Foundation
public extension DispatchQueue {
private static var _onceTracker = [String]()
class func once(file: String = #file, function: String = #function, line: Int = #line, block:()->()) {
let token = file + ":" + function + ":" + String(line)
once(token: token, block: block)
}
/**
Executes a block of code, associated with a unique token, only once. The code is thread safe and will
only execute the code once even in the presence of multithreaded calls.
- parameter token: A unique reverse DNS style name such as com.vectorform.<name> or a GUID
- parameter block: Block to execute once
*/
class func once(token: String, block:()-> ()) {
objc_sync_enter(self)
defer { objc_sync_exit(self) }
if _onceTracker.contains(token) {
return
}
_onceTracker.append(token)
block()
}
}
2.3 调用
import UIKit
class DemoViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//print(SoundTools.sharedTools)
//print(SoundTools.sharedTools2)
print(SoundTools.sharedTools3)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//print(SoundTools.sharedTools)
//print(SoundTools.sharedTools2)
print(SoundTools.sharedTools3)
}
}
3.OC & Swift 混合开发
3.1 Swift 调用 OC
3.1.1 在项目的桥接头文件/项目名称-Bridging-Header.h 中 添加 .h 文件
//目的:让Swift 能够调用 OC
//使用 让所有 Swift 需要访问的 OC 的头文件在此处引入
#import "NetworkTools.h"
3.1.2 调用
import UIKit
class DemoViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print(NetworkTools.shared())
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print(NetworkTools.shared())
}
}
3.2 OC 调用 Swift
3.2.1 ProductName-Swift.h 注意 ProductName 不能包含中文和数字的组合~
点击项目,选择 TARGETS 中 Build Settings 选项卡,索搜 Product Name 修改值为 单例演示, 重新 Clean Build 项目
3.3.2 调用
#import "ViewController.h"
//ProductName-Swift.h 注意 ProductName 不能包含中文和数字的组合
//Swift 调用 OC 不会有问题
//但是 OC 无法访问 Swift 中的特殊语法,列如: 枚举!
#import "单例演示-Swift.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%@", [SoundTools sharedTools2]);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"%@", [SoundTools sharedTools2]);
}
@end