像这样使用 Singleton 来表示“API Manager”对象是一种典型的设计模式:-
class APIManager {
let ENDPOINT_URL = "http://remote-server-fqdn.com"
var storage : Storage!
var currentlyLoggedIn = false
class var sharedInstance: APIManager {
struct Static {
//---to contain the one and only instance of this class---
static var instance: APIManager!
//---a token to ensure that the class is only instantiated once---
static var token: dispatch_once_t = 0
}
//---executes a block object once and only once for the lifetime of an application---
dispatch_once(&Static.token) {
//---creates an instance of this class---
Static.instance = APIManager()
Static.instance.storage = Storage.sharedInstance
}
//---returns the instance of this class---
return Static.instance
}
这确保我们有一个 APIManager
对象,具有一致的 token ,我们可以在 ViewController 或 Model 方法的不同部分使用它。问题不大,也很容易理解。
问题
但是,问题是 --- 如果我使用 Alamofire 或 AFNetworking 等库作为方法到我的 APIManager
类?
这些(异步)方法嵌套在我的 Singleton 类中是否会导致任何意外的性能问题或意外的副作用?
我知道 async
服务器 API 调用或 dispatch_async
方法将使用 GCD 并且仍然可以实现并发。
作为附加问题:这种并发是通过单例的异步方法调用并发并行还是并发但不并行实现的?
例如,像这样:-
class APIManager {
// .... same block of code as above for declaring dispatch_once above.
// additional code which are API server calls (and async by nature) here
func loginRequest(username : String, password : String, completion: (loginSuccess : Bool) -> Void) {
// Alamofire.request ...
}
func getRequest(...) {
// Alamofire.request ...
}
func postRequest(...) {
// Alamofire.request ...
}
func testAsync() {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
println("just do something asynchronously")
}
}
}
最佳答案
这里有几个有效的正交问题。第一个问题是安全的一次性初始化。您似乎可以控制它 (dispatch_once
)。下一个问题是使用单例来抽象出外部依赖。太好了——它可以帮助测试、后期迁移、重构等。看起来你已经控制住了它,除非我遗漏了某些部分,否则你应该让那部分保持简单和“薄”尽可能。
然后您似乎在问是否应该在同一个 API 抽象类中构建更复杂的操作,我会说答案可能是“不”。为此开设其他类(class)。听起来那里可能还存在一些重要的并发问题(即共享状态),但一如既往,没有 Elixir ——你只需要自己解决这些问题。
处理共享状态的一种常见模式是拥有一个私有(private)调度队列,并让所有读取或写入共享状态的操作使用 dispatch_sync
和 dispatch_barrier_sync
分别。但这只是一个简单的样板模式,用于在并发编程环境中管理共享状态(即防止不同的线程干扰彼此的读/写);它对特定于 API/应用程序的相互依赖性没有任何作用(例如,如果您想在初始登录/注册调用仍在等待回复时延迟所有其他 API 调用。)后者是您必须自己编写的内容。
关于具有 dispatch_async/asynchronous 方法的 iOS Singleton API 管理器 : what's the implication?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27955747/