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)
}
}
}