以线程安全的方式实例化可选的Realm对象

时间:2017-07-26 15:33:49

标签: ios swift swift3 realm

我要做的是设置一系列可以通过实例变量访问的AVPlayers。一切都存储在Realm中,我在前一个视图中使用所有Realm vars实例化了Collection。加载视图后,我想加载所有播放器,然后使用位置中的一些参数触发它们。问题是,当locationManager被调用时,玩家会在玩家实例上返回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?
}

1 个答案:

答案 0 :(得分:2)

由于您使用忽略的属性而导致您的问题存在,而Realm并未保留这些属性。根据{{​​3}} GitHub关于忽略属性的问题,您遇到的是预期的行为。

来自链接问题:

  

“忽略的属性只能保证一致   单个Swift实例,但从集合中检索对象   每次都会创建一个新的Swift实例,从而实现您的行为   见“。

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

总结一下,您将无法在集合中使用忽略的Realm属性。