Swift3,你必须把这个弱变量框起来,对吗?
我有四个关于装箱弱引用的常见过程的模糊问题 为了演示这些问题,这里有一个通知系统,Swift3,你必须把这个弱变量框起来,对吗?,swift3,weak-references,boxing,Swift3,Weak References,Boxing,我有四个关于装箱弱引用的常见过程的模糊问题 为了演示这些问题,这里有一个通知系统,Notes 你会像这样使用它 class SyncedCell: UITableViewCell, Notes { override func layoutSubviews() { ... listen(forNote: "soloCell") } func editing() { say(note: "soloCell")
Notes
你会像这样使用它
class SyncedCell: UITableViewCell, Notes {
override func layoutSubviews() {
...
listen(forNote: "soloCell")
}
func editing() {
say(note: "soloCell")
...
input.becomeFirstResponder()
}
func note() {
print("Hooray, I got a note..")
editingCancel()
}
因此,Notes
的代码如下
对于一个给定的键(比如“soloCell”),您只需保留一个数组,该数组包含对调用该键时希望获取消息的任何对象的引用
当然,这些必须是弱引用
所以,当一个新的对象到达,需要在列表中记忆
var b:_Box = _Box()
b.p = self
_notes[k]?.append(b)
(函数“listen”只是将该对象添加到该键的项列表中。“say”函数会遍历该键的侦听项列表:对于每个项,如果该项在此期间没有消失,则会发送一条消息。)
所以!据我所知,您不能保留弱引用数组
你必须把它们包装起来,正如你在下面的kodes中看到的那样
中,任何对象都是基础。那是最好的吗
:class
。这是令人不安的,我不确定是否应该struct _Box {
weak var p: AnyObject?
// note: I prefer to spell out the assigment,
// rather than have a convenience initializer here
}
var _notes:[String:[_Box]] = [:]
protocol Notes {
func note()
}
extension Notes where Self:AnyObject {
func listen(forNote k: String) {
if _notes.index(forKey: k) == nil {
_notes[k] = []
}
var b:_Box = _Box()
b.p = self
_notes[k]?.append(b)
}
func say(note k:String) {
if let _n = _notes[k] {
var k:Int = 0
print("notes.4 saying......")
for b in _n {
let p = b.p
if (p == nil) {
print("\(k) notes.4 there's one that's been removed")
}
else {
print("\(k) notes.4 sending ok...")
(p as! Notes).note()
}
k = k + 1
}
}
__noteCleaner()
}
func __noteCleaner() {
for var (k, _n) in _notes {
let kn = _n.count
for i in (0..<kn).reversed() {
let p = _n[i].p
if (p == nil) {
_n.remove(at: i)
let newk = _n.count
print("notes.4, removed a dud listener for key \(k) new length is \(newk)")
}
}
if (_n.count == 0) {
print("notes.4, removed a seemingly unused key \(k)")
_notes.removeValue(forKey: k)
}
}
}
struct\u框{
弱var p:任何对象?
//注:我更愿意详细说明分配,
//而不是在这里有一个方便的初始值设定项
}
变量注释:[字符串:[[u框]]=[:]
协议说明{
func note()
}
扩展注释,其中Self:AnyObject{
func listen(forNote k:String){
如果注释索引(forKey:k)=nil{
_注释[k]=[]
}
变量b:_-Box=_-Box()
b、 p=自我
_注[k]?.追加(b)
}
func say(注k:字符串){
如果让_n=_注释[k]{
变量k:Int=0
打印(“注释4表示……”)
对于b in n{
设p=b.p
如果(p==nil){
打印(“\(k)注释。4有一个已删除”)
}
否则{
打印(“\(k)注释。4发送确定…”)
(p as!Notes)
}
k=k+1
}
}
__noteCleaner()
}
func _unoteCleaner(){
对于票据中的var(k,_n){
让kn=计数
因为在(0..中,我将专注于问题的核心
您正试图通过注册主体上的观察者来实现观察者(侦听器)模式。我猜主体将手动调用每个观察者
有一种更简单的方法来实现这一点。你可以使用单例。观察者将在单例上注册,当发生重要的事情时,主体将通知单例
这有一个特殊的类,NotificationCenter
。它只保留无主引用
代表不是为一个观察者制作的,也不是为多个观察者制作的
当然,有一种简单的方法可以通过将引用包装到结构/对象中来实现弱引用数组,请参见
然而,我认为您的问题是由您的体系结构引起的。您将视图类与模型类混合在一起,这不是一个好主意
具体回答您的问题:
不。我相信Swift邮件列表中关于这一点的讨论以“您可以包装它”结束。您不必如此简单地包装它。您可以编写自己的数组版本,在内部进行包装
使用泛型而不是AnyObject
,请参见上面的链接问题
是的,这是令人不安的。这是可能的,因为您实际上只在任何对象
(即类)上使用它,并且您正在删除框
中的类型。使用框。p
声明为注释
这将不起作用,除非注释
是类
协议
这是正确的。请参阅。一个简单的解决方法是在释放侦听器时手动删除侦听器(在deinit
)
相关:你也可以使用函数currying来保留弱引用。我基于此编写了一个事件通知系统。@benzi,谢谢,这需要一些思考。也许有一天你可以在这里用一句话给出一个非常简短的答案。我将再次回顾你的文章,谢谢。嗨,Sulthan!正如你所说,(1)它是一个单例。(_notes是一个全局的-本质上是一个单例)。正如你所说(2)观察者在单例中注册(注意listen#
在顶部的示例代码中)(3)当发生某件事时会通知单例(注意say#
在顶部的示例中).继续,你提到了NSNotificationCenter
-这真是一派胡言;我从未加入过使用它的团队。在Swift时代,人们基本上可以说“永远不要使用它”。下一步:)您提到存储弱引用数组的一种常见方法是将它们装箱。这是真的;我在这里给出的示例代码中给出了一个极好的、完美的例子。关于上述常见技术,我有四个具体的、详细的问题-参见1到4!最后Sulthan!:)您提到了一个“问题”在最后一段中,您提到了MVC。我不确定您的意思:我给出的通知用法示例是,当您同步单元格时。这是唯一的方法