Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 领域-Can';删除对象后不能使用该对象_Ios_Objective C_Swift_Realm_Realm List - Fatal编程技术网

Ios 领域-Can';删除对象后不能使用该对象

Ios 领域-Can';删除对象后不能使用该对象,ios,objective-c,swift,realm,realm-list,Ios,Objective C,Swift,Realm,Realm List,我的应用程序中有一个视频播放器。集合视图中有一个视频列表。如果点击其中一个单元格,将显示一个新的视图控制器来播放选定的视频。此外,您还可以在此新的视图控制器中循环浏览集合视图中的所有视频,因为将传递整个列表 问题是: 当用户在PlayerVC中时,他们可以禁用视频。如果他们这样做,我将从域中删除视频对象。但是,这会导致: 由于未捕获的异常“RLMException”而终止应用程序,原因是:“对象已被删除或无效。” 基本上,如果用户在PlayerVC中观看视频,并且他不喜欢视频,我希望他们暂时仍能

我的应用程序中有一个视频播放器。集合视图中有一个视频列表。如果点击其中一个单元格,将显示一个新的视图控制器来播放选定的视频。此外,您还可以在此新的视图控制器中循环浏览集合视图中的所有视频,因为将传递整个列表

问题是: 当用户在
PlayerVC
中时,他们可以禁用
视频。如果他们这样做,我将从域中删除
视频
对象。但是,这会导致:

由于未捕获的异常“RLMException”而终止应用程序,原因是:“对象已被删除或无效。”

基本上,如果用户在
PlayerVC
中观看视频,并且他不喜欢视频,我希望他们暂时仍能观看视频。
但是当他们离开
PlayerVC
时,
FavoritesVC
中的收藏视图应该更新,不再显示
video

当我删除
Video
对象时,我使用Realm的
delete
方法

这是我保存
视频
对象列表的代码:

/// Model class that manages the ordering of `Video` objects.
final class FavoriteList: Object {
    // MARK: - Properties

    /// `objectId` is set to a static value so that only
    /// one `FavoriteList` object could be saved into Realm.
    dynamic var objectId = 0

    let videos = List<Video>()

    // MARK: - Realm Meta Information

    override class func primaryKey() -> String? {
        return "objectId"
    }
}
/// This view controller uses `AVFoundation` to play the videos from `FavoriteCollectionViewController`.
class PlayerViewControllerr: UIViewController {

    /// This `videos` is passed from `FavoriteCollectionViewController`
    var videos = List<Video>()

    // HELP: The app crashes here if I unfavorite a `Video`.
    @IBAction func didToggleStarButton(_ sender: UIButton) {
        let realm = try! Realm()
        try! realm.write {
            let videoToDelete = videos[currentIndexInVideosList] /// Get the video that is currently playing
            realm.delete(videoToDelete)
        }
    }
}
这是我在集合视图中显示
视频
对象的代码(注意:我使用
RealmCollectionChange
更新集合视图以删除和插入单元格):

最终,我希望将不受欢迎的
视频对象从领域中完全删除。只是不确定在这种情况下如何/何时进行

有什么想法吗

更新1 解决此问题的一个选项是:

  • 制作
    视频的非托管副本
    副本,并使用该副本启动视图控制器的UI
我认为这可能是可行的:

  • PlayerVC
    将收到两个
    List
    ,一个保存在Realm中的原始列表和一个该
    List
    的副本,以启动UI。让我们调用列表
    收藏夹列表
    复制列表

  • 因此,在
    didToggleStarButton
    的内部,我们将执行以下操作:

代码:

///此视图控制器使用“AVFoundation”播放来自“FavoriteCollectionViewController”的视频。
类PlayerViewController:UIViewController{
///允许用户对“视频”进行喜爱和不喜爱的按钮`
@IBVAR启动按钮:UIButton!
///这是从“FavoriteCollectionViewController”传递的`
var favoriteList:favoriteList!
///“FavoriteList”视频的副本,用于为用户界面供电。
var copiedList:List!
var currentIndexOfVideoInCopiedList:Int!
重写func viewDidLoad(){
超级viewDidLoad()
//复制favoriteList以启动UI。
var copiedVideos=[Video]()
对于favoriteList.videos中的视频{
let unmanagedVideo=视频(值:视频)
copiedVideos.append(非托管视频)
}
self.copiedList.append(复制视频)
}
//帮助:如果我不喜欢“视频”,应用程序将在此崩溃。
@iAction func didToggleStarButton(u发件人:UIButton){
//在这里做不利和有利的事情。
//不利因素的一个例子:
让realm=try!realm()
试试看!写吧{
让videoToDeleteFromFavoriteList=favoriteList.videos[currentIndexOfVideoInCopiedList]///获取当前正在播放的视频
域删除(videoToDeleteFromOriginalList)
}
//根据“视频”是否受欢迎,将星形按钮更新为新图像。
starButton.isSelected=/…根据“收藏夹列表”中的“视频”是否存在进行更新。
}
}

有什么想法吗?

这里是解决方案。检查它是否有效

 class PlayerViewControllerr: UIViewController {

          var arrayForIndex = [Int]()
          var videos = List<Video>()


          @IBAction func didToggleStarButton(_ sender: UIButton) {
               self.arrayForIndex.append(currentIndexInVideosList)     
           }

         @overide func viewWillDisappear(_ animated : Bool){
              super.viewWillDisappear(animated)
              for i in arrayForIndex{
                 let realm = try! Realm()
        try! realm.write {
            let videoToDelete = videos[i] /// Get the video that is currently playing
            realm.delete(videoToDelete)
        }
       }
        }
class PlayerViewController:UIViewController{
变量arrayForIndex=[Int]()
var videos=List()
@iAction func didToggleStarButton(u发件人:UIButton){
self.arrayForIndex.append(currentIndexInVideosList)
}
@俯视功能视图将消失(uu动画:Bool){
超级。视图将消失(动画)
因为我在arrayForIndex{
让realm=try!realm()
试试看!写吧{
让videoToDelete=videos[i]///获取当前正在播放的视频
域删除(videoToDelete)
}
}
}

由于许多架构原因,这一点肯定很棘手

你是对的,你可以简单地从
收藏列表中删除该对象。视频
,然后在关闭控制器时将其从域中正确删除,但你是对的,如果用户单击“主页”按钮,或者在此之前应用程序崩溃,你将得到一个无头视频对象。你需要能够使你可以追踪到

有两件事你可以考虑。

  • isDeleted
    属性添加到
    Video
    类中。当用户不喜欢视频时,从
    FavoriteList中删除
    Video
    对象。videos
    ,将该属性设置为
    true
    ,但将其保留在Realm中。稍后(当应用程序退出或视图控制器关闭时),然后可以对
    isDeleted
    true
    的所有对象执行常规查询,然后将其删除(这解决了无头问题)
  • 由于您的体系结构需要一个视图控制器,该视图控制器依赖于可以从其下删除的模型,这取决于您从该
    视频
    对象中使用的信息量,因此可能更安全的做法是创建
    视频
    副本的非托管副本,并使用该副本为视图控制器的UI供电。您可以创建一个新的通过执行
    让unmanagedVideo=Video(值:Video)
    复制现有领域对象

我更新了我的问题以显示我的模型调用
/// This view controller uses `AVFoundation` to play the videos from `FavoriteCollectionViewController`.
class PlayerViewControllerr: UIViewController {

    /// This `videos` is passed from `FavoriteCollectionViewController`
    var videos = List<Video>()

    // HELP: The app crashes here if I unfavorite a `Video`.
    @IBAction func didToggleStarButton(_ sender: UIButton) {
        let realm = try! Realm()
        try! realm.write {
            let videoToDelete = videos[currentIndexInVideosList] /// Get the video that is currently playing
            realm.delete(videoToDelete)
        }
    }
}
/// This view controller uses `AVFoundation` to play the videos from `FavoriteCollectionViewController`.
class PlayerViewControllerr: UIViewController {

    /// A button to allow the user to favorite and unfavorite a `Video`
    @IBOutlet weak var starButton: UIButton!

    /// This is passed from `FavoriteCollectionViewController`
    var favoriteList: FavoriteList!

    /// A copy of the `FavoriteList` videos to power the UI.
    var copiedList: List<Video>!

    var currentIndexOfVideoInCopiedList: Int!

    override func viewDidLoad() {
        super viewDidLoad()

        // Make a copy of the favoriteList to power the UI.
        var copiedVideos = [Video]()

        for video in favoriteList.videos {
            let unmanagedVideo = Video(value: video)
            copiedVideos.append(unmanagedVideo)
        }

        self.copiedList.append(copiedVideos)
    }

    // HELP: The app crashes here if I unfavorite a `Video`.
    @IBAction func didToggleStarButton(_ sender: UIButton) {
        // Do the unfavoriting and favoriting here.


        // An example of unfavoriting:
        let realm = try! Realm()
        try! realm.write {
            let videoToDeleteFromFavoriteList = favoriteList.videos[currentIndexOfVideoInCopiedList] /// Get the video that is currently playing
            realm.delete(videoToDeleteFromOriginalList)
        }

        // Update star button to a new image depending on if the `Video` is favorited or not.
        starButton.isSelected = //... update based on if the `Video` in the `FavoriteList` or not.
    }
}
 class PlayerViewControllerr: UIViewController {

          var arrayForIndex = [Int]()
          var videos = List<Video>()


          @IBAction func didToggleStarButton(_ sender: UIButton) {
               self.arrayForIndex.append(currentIndexInVideosList)     
           }

         @overide func viewWillDisappear(_ animated : Bool){
              super.viewWillDisappear(animated)
              for i in arrayForIndex{
                 let realm = try! Realm()
        try! realm.write {
            let videoToDelete = videos[i] /// Get the video that is currently playing
            realm.delete(videoToDelete)
        }
       }
        }