Ios 如何跨UITableViewCell类的所有实例访问模型类的一个特定实例的属性?

Ios 如何跨UITableViewCell类的所有实例访问模型类的一个特定实例的属性?,ios,swift,uitableview,Ios,Swift,Uitableview,我目前正在构建一个iOS应用程序,在其中一个视图中,UITableView的每一行中都包含一个UICollectionView,这样用户可以向下滚动整个视图,但也可以向右滚动每一行。例如,它看起来就像Spotify的主页。应用程序的目的也是播放声音文件;单击其中一个集合视图单元格时,声音将播放 为此,我创建了一个自定义UITableViewCell类。控制此视图的UIViewController使用IBOutlet将该类引用到包含这些自定义表视图单元格的UITableView,而自定义UITab

我目前正在构建一个iOS应用程序,在其中一个视图中,UITableView的每一行中都包含一个UICollectionView,这样用户可以向下滚动整个视图,但也可以向右滚动每一行。例如,它看起来就像Spotify的主页。应用程序的目的也是播放声音文件;单击其中一个集合视图单元格时,声音将播放

为此,我创建了一个自定义UITableViewCell类。控制此视图的UIViewController使用IBOutlet将该类引用到包含这些自定义表视图单元格的UITableView,而自定义UITableViewCell类使用IBOutlet将其内部的UICollectionView引用到该UICollectionView。然后,我为这些UICollectionViewCell创建了另一个自定义类,该类只能在自定义UITableViewCell类中使用

问题是,我想知道,在全球范围内,是否有声音在播放。但是,自定义UITableViewCell类的每个实例都会创建其自己的模型实例,其中属性isAnythingPlaying存在,因此访问此属性只能告诉我当前UITableViewCell中是否有声音文件正在播放。为清楚起见:

class Model {

    // (other properties would normally be here)

    var isAnythingPlaying: Bool = false

    // (other functions would normally be here)

    func getIsAnythingPlaying() {
    /*
    The problem with this method is that it will update a property (isAnythingPlaying)
    that needs to contain the same value no matter which cell of the table view 
    (CustomTableViewCell) is accessing it.

    This is just pseudocode for the real method, which works as intended.
    */

        if (somethingIsPlaying) {
            isAnythingPlaying = true
        }

        else {
            isAnythingPlaying = false
        }
    }
}
然后,我的CustomTableViewCell类如下所示:

class CustomTableViewCell: UITableViewCell! {

    @IBOutlet weak var collectionView: UICollectionView!

    var customModel = Model!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
        collectionView.delegate = self
        collectionView.dataSource = self

        customModel = Model()

    // (other functions would normally be here)

    }
}

extension CustomTableViewCell: UICollectionViewDelegate, 
  UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    ***************************************************************
    // at this point the value model.isAnythingPlaying will expectedly be different
    // for each instance of the UITableViewCell. If anything is playing within that
    // particular cell (row), it will be true; otherwise, false.
    ***************************************************************

}

我可以做些什么来让所有CustomTableViewCell对象访问相同的isAnythingPlaying变量吗?我曾考虑将其放在捆绑包中的文本文件中,并让代码将文本文件从“true”切换到“false”,但这似乎太荒谬了,无法实际尝试。

基本上,您需要一个单例。只需要一个bool变量就非常简单:

class MyModel {
    var isAnythingPlaying: Bool = false

    static let shared: MyModel = {
        let instance = MyModel()
        return instance
    }()
}
要从视图类中引用,请执行以下操作:

if MyModel.shared.isAnythingPlaying {
    // do something
}
在这个简单的实现中,将isAnythingPlaying变量设置为true或false的逻辑可以在任何地方发生

实际上,您需要更多的逻辑,可能需要保留正在播放的对象的ID列表,因为您不希望播放器在播放其他内容时停止将变量设置为false。如果采用这种方法,您可以为singleton提供一个计算变量:

var currentlyPlayingIDs: [Int] = []
var isAnythingPlaying {
    get {
        return !self.currentlyPlayingIDs.isEmpty
    }
}
然后,当项目开始播放时,它可以通过以下方式更新单例:

MyModel.shared.currentlyPlayingIDs.append(self.id)
同样,当它停止播放时,删除它的ID

可能需要对无关对象进行通知处理和发布,以共享更改的内容

如果这些操作发生在主UI线程之外,您需要确保更改是线程安全的,这远远超出了问题的范围,但我想我会提到它

以下是Swift singleton模式Apple文档:


您可以使用一个
静态
属性,您可以通过
Model.isAnythingPlaying=true
直接在
模型上设置该属性。将变量声明为静态会将该属性放在类本身上,并确保该属性只有一个值。如果要从在一个模型的实例中,您可以像上面一样引用类名,或者使用
Self
关键字,注意大写字母“S”

class Model {
    // static property that every instance can read/write by using Self.isAnythingPlaying
    // any object outside of the Model class can access the same value by
    // accessing the property on the class ex.  
    // if Model.isAnythingPlaying { 
    // }
    static var isAnythingPlaying: Bool = false

    func getIsAnythingPlaying() {
        return Self.isAnythingPlaying
    }
}