领域 - 删除后无法使用对象

2023-11-30

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

问题是: 当用户处于PlayerVC,他们可以取消收藏Video。如果他们这样做,我会删除Video来自 Realm 的对象。然而,这会导致:

Terminating app due to uncaught exception 'RLMException', reason: 'Object has been deleted or invalidated.'

基本上,如果用户正在观看视频PlayerVC他取消了某个视频的收藏,我希望他们暂时仍能观看该视频。但当他们离开PlayerVC,集合视图FavoritesVC应该更新并且不显示Video不再有。

当我删除一个Video我使用 Realm 的对象delete method.

这是我的代码来保存列表Video对象:

/// 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"
    }
}

这是我的Video类有一个isFavorite财产:

final class Video: Object {
    // MARK: - Properties

    dynamic var title = ""
    dynamic var descriptionText = ""
    dynamic var date = ""
    dynamic var videoId = ""
    dynamic var category = ""
    dynamic var duration = 0
    dynamic var fullURL = ""
    dynamic var creatorSite = ""
    dynamic var creatorName = ""
    dynamic var creatorURL = ""

    // MARK: FileManager Properties (Files are stored on disk for `Video` object).

    /*
        These are file names (e.g., myFile.mp4, myFile.jpg)
    */
    dynamic var previewLocalFileName: String?
    dynamic var stitchedImageLocalFileName: String?
    dynamic var placeholderLocalFileName: String?

    /*
        These are partial paths (e.g., bundleID/Feed/myFile.mp4,     bundleID/Favorites/myFile.mp4)
        They are used to build the full path/URL at runtime.
    */
    dynamic var previewLocalFilePath: String?
    dynamic var stitchedImageLocalFilePath: String?
    dynamic var placeholderLocalFilePath: String?

    // Other code...
}

这是我的代码来显示Video集合视图中的对象(注意:我使用RealmCollectionChange更新集合视图以删除和插入单元格):

/// This view controller has a `collectioView` to show the favorites.
class FavoriteCollectionViewController: UIViewController {
    // MARK: Properties

    let favoriteList: FavoriteList = {
        let realm = try! Realm()
        return realm.objects(FavoriteList.self).first!
    }()

    // Realm notification token to update collection view.
    var notificationToken: NotificationToken?

    // MARK: Collection View

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return favoriteList.videos.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FavoritesCollectionViewCell.reuseIdentifier, for: indexPath) as! FavoritesCollectionViewCell
        cell.video = favoriteList.videos[indexPath.item]

        return cell
    }

    // I pass this lst forward to the PlayerVC
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if let playerVC = self.storyboard?.instantiateViewController(withIdentifier: "PlayerViewController") as? PlayerViewController {
            // I pass the videos here.
            playerVC.videos = favoriteList.videos
            self.parent?.present(playerVC, animated: true, completion: nil)
        }
    }

    // MARK: Realm Notifications


    func updateUI(with changes: RealmCollectionChange<List<Video>>) {
        // This is code to update the collection view.
    }
}

最后,这是允许用户在所有内容之间播放和循环的代码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)
        }
    }
}

最终我想要的是Video不喜欢的物体从 Realm 中完全删除。只是不确定在这种情况下如何/何时执行。

有什么想法吗?

Update 1

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

  • 制作一份非托管副本Video复制,并使用它来驱动视图控制器的 UI。

我认为这可能起作用的方式是这样的:

  • The PlayerVC将收到两个List,保存在 Realm 中的原始文件及其副本List为 UI 供电。让我们调用列表favoriteList and copyList.

  • 所以里面didToggleStarButton我们会做这样的事情:

Code:

/// 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.
    }
}

有什么想法吗?


由于许多架构原因,这绝对是棘手的。

你是对的could只需将对象从FavoriteList.videos然后在关闭控制器时从 Realm 中正确删除它,但你是对的,如果用户单击主页按钮,或者应用程序在此之前崩溃,你最终会得到一个无头视频对象。您需要能够确保您可以跟踪它。

您可能可以考虑以下几件事。

  • Add an isDeleted财产给Video班级。当用户取消收藏视频时,删除Video对象来自FavoriteList.videos,将该属性设置为true,但将其留在 Realm 中。稍后(当应用程序退出或视图控制器被关闭时),您可以对所有对象进行一般查询,其中isDeleted is true然后删除它们(这解决了无头问题)。
  • 由于您的架构需要一个视图控制器,该视图控制器依赖于可以从其下方删除的模型,具体取决于您使用的信息量Video对象,制作该对象的非托管副本可能更安全Video复制,并使用它来驱动视图控制器的 UI。您可以通过执行以下操作创建现有 Realm 对象的新副本let unmanagedVideo = Video(value: video).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

领域 - 删除后无法使用对象 的相关文章

  • Swift 自定义 UITableViewCell 标签始终为零

    我已经被这个问题困扰好几天了 所以如果有人能提供帮助 我会很高兴 我正在尝试创建一个动态 UITableView 为此我创建了一个自定义 UITableView 子类 并且还创建了一个自定义 UITableViewCell 子类 因为我需要
  • 如何从一个 ViewController 到另一个 ViewController 访问对象

    提供一些技巧来摆脱以下情况 描述 我有两个 viewController 即视图控制器1 and 视图控制器2 所以显然我们有ViewController1 h ViewController1 m and ViewController2 h
  • 获取 UIView 的视图控制器(iphone)

    我这样做是为了获得视图 self superview viewWithTag 10 但我怎样才能获得该视图的视图控制器 就像您可以获得视图控制器的视图一样 我想采用另一种方式 以便我可以向该视图控制器发送消息 调用方法 例如 self su
  • “StorageReference”类型的值没有成员“put”[重复]

    这个问题在这里已经有答案了 我更新到 firebase storage 4 0 现在收到此错误 指出 storageRef 没有成员 put 它以前在旧版本的 Firebase 中有效 if let selectedImage select
  • MFMailcomposeviewcontroller 发送按钮被禁用

    有没有人遇到这样的问题MFMailcomposeviewcontroller发送按钮被禁用 变灰 取消按钮工作得很好 这似乎是一个新错误 如果本机邮件应用程序从 iPhone 中删除 从 iOS 10 开始允许 则可能会发生这种情况 在这种
  • 如何将 Swift 字符串传递给 C 函数?

    我在将字符串从 swift 传递到用 c 编写的函数时遇到严重问题 我正在尝试在我的快速代码中执行此操作 var address 192 168 1 2 var port 8888 initSocket address port c 函数如
  • 为什么类方法中的“self = [[Rectangle alloc] init]”是错误的?

    在 Apple 的文档 Objective C 编程语言 中 第 48 页说道 Rectangle rectangleOfColor NSColor color self Rectangle alloc init BAD self setC
  • Swift 从 Realm 中删除对象

    我有领域对象保存来自 JSON 响应的列表 但现在如果该对象不再从 JSON 中出现在列表中 我需要删除该对象 我怎么做到这一点 这是我的领域初始化 func listItems dic Array lt String AnyObject
  • 如何多次从 NSHTTPCookieStorage 中清除 cookie?

    我的桌面应用程序连接到 Google App Engine 上托管的网络应用程序 一旦通过身份验证 它就会获得一个 authtoken cookie 并为所有未来的请求传递该 cookie 这一切都有效 但现在我想添加 退出 我尝试像这样实
  • UITouch移动速度检测

    我正在尝试检测触摸移动的速度 但并不总能得到我期望的结果 补充 速度峰值太多 任何人都可以发现我是否在做一些时髦的事情或建议更好的方法吗 void touchesBegan NSSet touches withEvent UIEvent e
  • iOS 5 中的新错误:WebKit 丢弃了未捕获的异常

    我正在尝试加载一个UIWebView与 Facebook OAuth 授权 URL 我使用以下代码 当我的UIWebView加载 Facebook 登录页面 我输入我的凭据 然后按 登录 按钮 当我点击按钮时 我收到以下错误 WebKit
  • EKEvent接受邀请

    你如何接受EKEventiOS 中的邀请 我知道这有可能梦幻般的 日历 5和其他日历应用程序具有此功能 但我没有看到公开的非只读属性来更改用户有关事件的状态 知道如何做到这一点吗 Thanks 事实证明 经过更多研究后 所有这些应用程序都只
  • 录制视频/音频时播放系统声音

    当我开始录制视频时 我试图按照苹果的要求播放 嘟嘟 声 我通过 SO 和其他来源发现 当您有音频输入而没有进行某些配置时 您无法播放声音 这是我尝试的配置方法 private void SetupAudio beepSound AssetB
  • 为什么我不能在 func Swift 中使用 self

    我试图自行将 SKSpriteNodes 添加到函数中的视图中 但 Xcode 不允许我这样做 它给了我错误 使用未解析的标识符 self func indicate if test 0 var large CGFloat largest
  • 修剪 UIImage 边框

    这是我想要修剪的图像的示例 我想去掉图像周围的边框 在本例中是顶部和底部的黑条 我在Github上找到了一个库 CKImageAdditions https github com cmkilger CKImageAdditions 但是它似
  • 使用react-native使用WebView设置用户代理

    我想修改 WebView 中的用户代理字符串 以便在服务器端我可以检测到请求来自我的反应本机应用程序 我想使用 WebView 中的 source 属性来做到这一点 对于 IOS 和 Android 我该如何执行此操作 您只需将其设置为 W
  • 是否可以使用 UITableViewStylePlain 禁用 UITableView 中的浮动标题?

    我正在使用一个UITableView布局内容 页面 我使用表视图的标题来布局某些图像等 如果它们不浮动而是保持静态 就像样式设置为时那样 我更喜欢它UITableViewStyleGrouped 其他则使用UITableViewStyleG
  • Objective C“#if”语法

    我对 如果 或 如果 有点困惑 if当我查看一些类时我看到的语法 例如 if someConstant someNumber do something elif etc versus if someConstant someNumber d
  • 将子视图控制器添加到当前视图控制器

    我正在尝试使用以下代码在代码中将子视图控制器添加到情节提要中的当前视图控制器 UIStoryboard storyboard UIStoryboard storyboardWithName Main bundle nil LogInTuto
  • 用于测试对象类型的通用 Swift 函数

    我正在尝试编写一个函数 该函数接受一个对象和一个类型作为参数 并返回一个布尔值 指示该对象是否属于给定类型 似乎没有 Type 类型 所以我不知道如何做到这一点 我能做的最好的就是 func objectIsType

随机推荐

  • iPhone - AVAudioRecorder - 如何录制到 mp3?

    我正在使用 3 0 SDK 提供的 AVAudioRecorder 类在我的应用程序中录制音频 我成功地能够录制到 caf aiff 文件 但我想录制成mp3 我尝试更改设置字典中的一些值 但我得到的只是一个空白文件 是否可以使用 AVAu
  • 一个 JVM 内多个独立的 H2 数据库

    是否可以同时启动和关闭多个H2JVM 中的数据库 我的目标是支持多租户为每个用户 帐户提供自己的数据库 每个帐户的数据很少 帐户之间的数据永远不会一起访问 比较或分组 每个帐户都与其他帐户完全分开 每个帐户每天仅短暂访问一次或每月几次 因此
  • 使用 Expression> 使值类型表现为引用类型

    我们知道 int 是一种值类型 因此以下内容是有意义的 int x 3 int y x y 5 Console WriteLine x says 3 现在 这里有一些代码 由于缺乏更好的术语 我们希望将两个变量 链接 到相同的内存位置 in
  • 添加代理到 PhantomJSDriver (Selenium C#)

    我想听一下 c 中 phantomjs selenium 驱动程序生成的流量 不幸的是 下面的代码不起作用 PhantomJSOptions phoptions new PhantomJSOptions phoptions AddAddit
  • 在 CUDA 中混合自定义内存管理和 Thrust

    在我的项目中 我实现了一个自定义内存分配器 以避免不必要的调用cudaMalloc一旦应用程序 预热 此外 我使用自定义内核进行基本数组填充 数组之间的算术运算等 并希望通过使用来简化我的代码Thrust并摆脱这些内核 设备上的每个数组都是
  • 测试输入的数字是否为三角形数

    我需要创建一个程序来测试用户输入的给定数字是否是三角形数字 我创建了一个脚本 只给出所有三角形数字的列表 但在这个程序中 用户需要输入一个数字 程序必须确定该数字是否是三角形 由于您引用的维基百科文章指出 An integer x is t
  • numpy 矩阵。将全 0 移动到每行的末尾

    给定 python numpy 中的一个矩阵 其中某些行有前导零 我需要将所有零移到行尾 例如 0 2 3 4 0 0 1 5 2 3 1 1 应该转化为 2 3 4 0 1 5 0 0 2 3 1 1 有没有什么好的方法可以在 pytho
  • 将上三角形条目的平面列表复制到完整矩阵?

    我在平面列表 连接行 中有对称矩阵的上三角形条目 包括对角线 我想用它们来填充整个矩阵 包括下三角形 最快的方法是什么 这是我目前的方法 如此简单的操作似乎需要做很多工作 import numpy as np def utri2mat ut
  • Prolog中指数为负时计算幂的规则?

    我有幂函数pow试图计算的值B的力量E 到目前为止我处理的案件 1 指数为02 指数非零 pow B 0 1 pow B E Result E2 is E 1 pow B E2 Result2 Result is B Result2 如何添
  • Gson.toJson 给出 StackOverFlowError,在这种情况下如何获取正确的 json? (公共静态类)

    我目前有以下课程 static final class TabInfo public final String tag public final Class class Bundle args tag tag clss class args
  • dijit.form.filteringselect 动态更改选项

    我有一个dijit form FilteringSelect组件 我想动态更改选项 但我从 dijit form FilteringSelect 及其 store 属性获取商店 商店里没有设置器功能 它可能是一个dojo store Rea
  • 求解大数的模线性同余

    我正在寻找一种比我在 stackoverflow 上找到的算法更好的算法来处理 4096 字节数 我正在达到最大递归深度 来自 stackoverflow 帖子的代码 我复制 粘贴了它 但丢失了原始链接 def linear congrue
  • Angular 从 HttpEvent<> 获取正文

    我正在通过调用该类的方法来执行获取请求AuthService return this http post
  • 升级到1.6版本后无法重新索引新产品

    我已将我的网站从版本 1 4 0 1 升级到版本 1 6 我已经从网站上删除了所有产品 并成功完成了 重新索引所有 当我尝试创建新产品并再次重新索引时 出现此错误 Product Attributes index process unkno
  • 在 R 中使用循环定义 case_when 的值

    我目前正在使用case when在我的数据中定义一个新变量 如下所示 data 46 lt NA data 46 lt case when data 35 1 data 36 data 35 2 data 37 data 35 3 data
  • AttributeError:'numpy.datetime64'对象没有属性'toordinal'

    我正在尝试画一个时间线 import datetime as da import matplotlib dates as dt Data df pd DataFrame A da datetime 2017 1 5 9 8 da datet
  • 注册我的 .net 程序集以实现 COM 互操作性不会公开我的方法

    好吧 我要疯了 我一直在尝试使一个简单的 net 程序集可见以用作 COM 对象 但它不起作用 我一直在尝试很多不同的方法 但没有一个有效 到目前为止 我得到的最接近的是属性 接口 手动注册等最少的一个 我有一个 vbscript 作为测试
  • 将 pandas 数据框保存为 csv 时如何保留 columns.name?

    初始问题 当我在 ipython 中运行以下命令时 import numpy as np import pandas as pd df pd DataFrame np round 9 np random rand 4 4 decimals
  • 在自定义 RCP 应用程序中使用 org.eclipse 剪切/复制/粘贴

    我正在开发一个 RCP 应用程序 我需要在此应用程序中剪切 复制 粘贴 由于已经有 eclipse 提供的命令 org eclipse ui edit copy 我想在编辑器中使用它们 例如 我已经将它们添加到工具栏 我玩了一下 但我不明白
  • 领域 - 删除后无法使用对象

    我的应用程序中有一个视频播放器 集合视图中有一个视频列表 如果您点击其中一个单元格 则会出现一个新的视图控制器来播放所选视频 此外 您还可以在这个新视图控制器中循环浏览集合视图中的所有视频 因为整个列表都会被传递 问题是 当用户处于Play