当需要自引用时,如何在Swift中初始化CBCentralManager [英] How to initialize CBCentralManager in Swift when a self reference is necessary
问题描述
什么是初始化CBCentralManager实例的好方法,该实例需要一个委托并且通常指向所有者类?
What are good ways to initialize an instance of CBCentralManager, which requires a delegate and is often pointing to the owning class?
我可以将属性声明为一个隐式解包的可选属性,但是按照一般惯例,这样做似乎并不像Swift一样,也不是很安全.
I could declare the property as an implicitly unwrapped optional but doing so as a general practice seems rather not Swift-like and not very safe.
或者,我可以将属性声明为可选属性.但是,由于CBCentralManager的初始化程序未声明为可失败的,因此这样声明实例似乎没有任何意义.
Alternatively, I can declare the property as an optional. But since CBCentralManager's initializers are not declared as failable, it doesn't seem to make sense to declare the instance as such.
隐式展开可选:
class MyUnwrappedOptional: NSObject, CBCentralManagerDelegate {
var centralManager: CBCentralManager!
func init() {
super.init()
centralManager = CBCentralManager(delegate: self, queue: nil, options:nil)
// Subsequent usages of centralManager in other methods of this class don't require additional unwrapping.
centralManager.scanForPeripheralsWithServices(services, options: nil)
}
}
使用可选:
class MyOptionalClass: NSObject, CBCentralManagerDelegate {
var centralManager: CBCentralManager?
func init() {
super.init()
centralManager = CBCentralManager(delegate: self, queue: nil, options:nil)
// Subsequent usages of centralManager in other methods of this class require optional checks:
if let central = centralManager {
central.scanForPeripheralsWithServices(services, options: nil)
}
// :: or ::
central!.scanForPeripheralsWithServices(services, options: nil)
}
}
这些是更优选的还是实现这一目标的另一种方法?
Is either of these more preferred or is there another way to achieve this?
推荐答案
在初始化每个没有默认值且不是默认值的非lazy
属性之前,无法在init
方法中使用self
可选(默认值为nil
).
There is no way to use self
in an init
method prior to initializing every non-lazy
property that has no default value and is not optional (which have a default value of nil
).
如果您总是在init
中初始化centralManager
,并且没有可能使其成为nil
的代码,那么我想说CBCentralManager!
声明是一个不错的选择.这是隐式展开的可选类型的主要目的之一.
If you always initialize centralManager
in init
, and you have no code that will potentially make it nil
, I would say that the CBCentralManager!
declaration is a good choice. That is one of the main purposes of the implicitly unwrapped optional type.
这是
有时候,从程序的结构中可以明显看出一个可选的
首次设置该值后,始终会有一个值.在这种情况下,
有助于消除检查和拆开可选值的必要性
每次访问它,因为可以安全地假定它具有一个
一直都很珍惜.
Sometimes it is clear from a program’s structure that an optional will
always have a value, after that value is first set. In these cases, it
is useful to remove the need to check and unwrap the optional’s value
every time it is accessed, because it can be safely assumed to have a
value all of the time. 这些类型的可选定义为隐式解包
可选的.您可以通过放置一个
感叹号(String!)而不是问号(String?)
您要设置为可选的类型. These kinds of optionals are defined as implicitly unwrapped
optionals. You write an implicitly unwrapped optional by placing an
exclamation mark (String!) rather than a question mark (String?) after
the type that you want to make optional. 如果程序逻辑确实允许它在某些时候使用 If the program logic does potentially allow for it to be 另一个可能的选择是让您将 One other possible option would be for you to declare your 这篇关于当需要自引用时,如何在Swift中初始化CBCentralManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
nil
.那么普通的可选类型是适当的选择.nil
at some point when it might be used. Then a normal optional type is the appropriate choice.centralManager
属性声明为centralManager
property as a lazy
property. If you do this it won't be created until you access it, but you will be able to reference self
and make it non-optional. When you need it to be created will govern if you use this option or not.lazy var centralManager: CBCentralManager = { [unowned self] () -> CBCentralManager in
CBCentralManager.init(delegate: self, queue: nil, options: [:])
}()