【问题标题】:Thread-safe way of instantiating optional Realm objects实例化可选领域对象的线程安全方式
【发布时间】:2017-07-26 15:33:48
【问题描述】:

我要做的是设置一系列可以通过实例变量访问的 AVPlayer。一切都存储在 Realm 中,我已经在上一个视图中使用所有 Realm 变量实例化了 Collection。视图加载后,我想加载所有播放器,然后使用位置中的一些参数触发它们。问题是,当 locationManager 被调用时,播放器会在 Player 实例上返回 nil

我猜这是因为locationManager 在单独的线程上被调用?如果是这种情况,确保玩家已被实例化的线程安全方法是什么?

这是locationManager 和加载器的视图

class WalkMapViewController: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate {
    /* …lots of outlets */
    var collection:Collection!

    override func viewDidLoad() {
        /* …lots of other init stuff */
        self.loadPlayers()
    }

    func loadPlayers() {
        // get a url from somewhere
        for (i,_) in self.collection.players.enumerated() {
            // loop through the players and load them
            self.collection.players[i].player = AVPlayer(url: url)
        }
    }

    func locationManager(_ manager:CLLocationManager, didUpdateLocations locations:[CLLocation]) {
        for (i, _) in self.collection.players.enumerated() {
            self.collection.players[i].play()
        }
    }
}

这是一个大大缩短的 Collection 类,它是一个 Realm 对象,在 ignoreProperties 中有 players

class Collection: Object, Mappable {
    var players = List<Player>()
}

这是 Player 类,它也是一个嵌入在 Collection 中的 Realm 对象,并且在 ignoreProperties 中有player

class Player: Object, Mappable {
    var player:AVPlayer?
}

【问题讨论】:

  • 这很可能与线程无关,如果你试图从另一个线程访问Realm 对象,你会得到一个错误而不是一个 nil 对象。是这一行:self.collection.players[i].play() 返回 nil 吗?
  • 是的@DávidPásztor,正确。在loadPlayers() 范围内可以访问播放器。
  • 遗憾的是,这是预期的行为,正如我所怀疑的,它与线程无关,而是与被忽略的属性有关。请参阅下面的完整解释我的答案。

标签: ios swift swift3 realm


【解决方案1】:

您的问题存在是因为您使用的是忽略的属性Realm 不会保留这些属性。根据this GitHub issue about ignored properties,您所体验的是预期的行为。

来自链接问题:

"被忽略的属性只保证在整个 单个 Swift 实例,但从集合中检索对象 每次都创建一个新的 Swift 实例,因此您的行为 见。”

这意味着locationManager(didUpdateLocations:) 中的self.collection.players[i] 实际上是您在loadPlayers() 中创建的同一Realm 对象的新Swift 实例,这对于普通Realm 属性来说不是问题,因为它们是从Realm 数据库中获取,但会导致忽略属性的问题,因为它们链接到特定的Swift 实例并且仅存在于内存中。因此,当您从集合(“List”中的Player 实例)中检索特定对象时,所有被忽略的属性都将丢失。

总而言之,您将无法在集合中使用被忽略的Realm 属性。

【讨论】:

  • 精彩,优雅地总结。感谢您解决问题。这可能是一个风格问题,但您认为存储 AVPlayer 的最佳方式是什么?作为视图上的属性(可能作为带有播放器引用的字典)?
  • 谢谢 :) 很高兴我能提供帮助,这实际上是关于 Realm 的一个有趣的实现问题,所以我很高兴遇到您的问题并对其进行了调查。没有一种好的方法可以解决这个问题,但是是的,将 AVPlayer 存储为视图控制器的属性似乎是一个不错的解决方案。是否将它们存储在字典或数组中(因为您将它们存储在 Realm 中的列表中,所以数组似乎是自然的选择)完全取决于您。只需确定查找 AVPlayer 实例的更简单方法(通过索引或按键)并使用该实现即可。
  • Realm 文档将我带向花园小径,该文档说ignoredProperties 在各个方面都是绝对正常的属性。感谢有关实施的帮助,我可能会将它们放在一个单例中,因为我需要它们在其他视图中。
  • 是的,文档在这个特定主题中有点误导。在寻找 GitHub 问题之前,我也在查看文档,但没有提供任何关于此问题的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
  • 1970-01-01
  • 2014-12-18
  • 2017-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多