Commit e083c6c2 authored by Felix Paul Kühne's avatar Felix Paul Kühne

library: fix KVC related pseudo-random crashes because we didn't remove the...

library: fix KVC related pseudo-random crashes because we didn't remove the observers on dealloc, so observed objects tried to access nil observers
parent d007ea0c
......@@ -27,6 +27,11 @@
@implementation VLCPlaylistCollectionViewCell
- (void)dealloc
{
[self _removeObserver];
}
- (void)awakeFromNib
{
if (SYSTEM_RUNS_IOS7_OR_LATER) {
......@@ -87,66 +92,77 @@
[self _updatedDisplayedInformationForKeyPath:keyPath];
}
- (void)_removeObserver
{
if ([_mediaObject isKindOfClass:[MLLabel class]])
[_mediaObject removeObserver:self forKeyPath:@"name"];
else if ([_mediaObject isKindOfClass:[MLShow class]])
[_mediaObject removeObserver:self forKeyPath:@"episodes"];
else if ([_mediaObject isKindOfClass:[MLShowEpisode class]]) {
[_mediaObject removeObserver:self forKeyPath:@"name"];
[_mediaObject removeObserver:self forKeyPath:@"files"];
[_mediaObject removeObserver:self forKeyPath:@"artworkURL"];
[_mediaObject removeObserver:self forKeyPath:@"unread"];
} else if ([_mediaObject isKindOfClass:[MLAlbum class]]) {
[_mediaObject removeObserver:self forKeyPath:@"name"];
[_mediaObject removeObserver:self forKeyPath:@"tracks"];
} else if ([_mediaObject isKindOfClass:[MLFile class]]) {
[_mediaObject removeObserver:self forKeyPath:@"computedThumbnail"];
[_mediaObject removeObserver:self forKeyPath:@"lastPosition"];
[_mediaObject removeObserver:self forKeyPath:@"duration"];
[_mediaObject removeObserver:self forKeyPath:@"fileSizeInBytes"];
[_mediaObject removeObserver:self forKeyPath:@"title"];
[_mediaObject removeObserver:self forKeyPath:@"thumbnailTimeouted"];
[_mediaObject removeObserver:self forKeyPath:@"unread"];
[_mediaObject removeObserver:self forKeyPath:@"albumTrackNumber"];
[_mediaObject removeObserver:self forKeyPath:@"album"];
[_mediaObject removeObserver:self forKeyPath:@"artist"];
[_mediaObject removeObserver:self forKeyPath:@"genre"];
[(MLFile*)_mediaObject didHide];
}
}
- (void)_addObserver
{
if ([_mediaObject isKindOfClass:[MLLabel class]])
[_mediaObject addObserver:self forKeyPath:@"name" options:0 context:nil];
else if ([_mediaObject isKindOfClass:[MLShow class]])
[_mediaObject addObserver:self forKeyPath:@"episodes" options:0 context:nil];
else if ([_mediaObject isKindOfClass:[MLShowEpisode class]]) {
[_mediaObject addObserver:self forKeyPath:@"name" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"files" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"artworkURL" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"unread" options:0 context:nil];
} else if ([_mediaObject isKindOfClass:[MLAlbum class]]) {
[_mediaObject addObserver:self forKeyPath:@"name" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"tracks" options:0 context:nil];
} else if ([_mediaObject isKindOfClass:[MLFile class]]) {
[_mediaObject addObserver:self forKeyPath:@"computedThumbnail" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"lastPosition" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"duration" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"fileSizeInBytes" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"title" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"thumbnailTimeouted" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"unread" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"albumTrackNumber" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"album" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"artist" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"genre" options:0 context:nil];
[(MLFile*)_mediaObject willDisplay];
}
}
- (void)setMediaObject:(MLFile *)mediaObject
{
if (_mediaObject != mediaObject) {
if ([_mediaObject isKindOfClass:[MLLabel class]]) {
[_mediaObject removeObserver:self forKeyPath:@"name"];
} else if ([_mediaObject isKindOfClass:[MLShow class]])
[_mediaObject removeObserver:self forKeyPath:@"episodes"];
else if ([_mediaObject isKindOfClass:[MLShowEpisode class]]) {
[_mediaObject removeObserver:self forKeyPath:@"name"];
[_mediaObject removeObserver:self forKeyPath:@"files"];
[_mediaObject removeObserver:self forKeyPath:@"artworkURL"];
[_mediaObject removeObserver:self forKeyPath:@"unread"];
} else if ([_mediaObject isKindOfClass:[MLAlbum class]]) {
[_mediaObject removeObserver:self forKeyPath:@"name"];
[_mediaObject removeObserver:self forKeyPath:@"tracks"];
} else if ([_mediaObject isKindOfClass:[MLFile class]]) {
[_mediaObject removeObserver:self forKeyPath:@"computedThumbnail"];
[_mediaObject removeObserver:self forKeyPath:@"lastPosition"];
[_mediaObject removeObserver:self forKeyPath:@"duration"];
[_mediaObject removeObserver:self forKeyPath:@"fileSizeInBytes"];
[_mediaObject removeObserver:self forKeyPath:@"title"];
[_mediaObject removeObserver:self forKeyPath:@"thumbnailTimeouted"];
[_mediaObject removeObserver:self forKeyPath:@"unread"];
[_mediaObject removeObserver:self forKeyPath:@"albumTrackNumber"];
[_mediaObject removeObserver:self forKeyPath:@"album"];
[_mediaObject removeObserver:self forKeyPath:@"artist"];
[_mediaObject removeObserver:self forKeyPath:@"genre"];
[(MLFile*)_mediaObject didHide];
}
[self _removeObserver];
_mediaObject = mediaObject;
// prevent the cell from recycling the current snap for random contents
self.thumbnailView.image = nil;
if ([_mediaObject isKindOfClass:[MLLabel class]]) {
[_mediaObject addObserver:self forKeyPath:@"name" options:0 context:nil];
} else if ([_mediaObject isKindOfClass:[MLShow class]])
[_mediaObject addObserver:self forKeyPath:@"episodes" options:0 context:nil];
else if ([_mediaObject isKindOfClass:[MLShowEpisode class]]) {
[_mediaObject addObserver:self forKeyPath:@"name" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"files" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"artworkURL" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"unread" options:0 context:nil];
} else if ([_mediaObject isKindOfClass:[MLAlbum class]]) {
[_mediaObject addObserver:self forKeyPath:@"name" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"tracks" options:0 context:nil];
} else if ([_mediaObject isKindOfClass:[MLFile class]]) {
[_mediaObject addObserver:self forKeyPath:@"computedThumbnail" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"lastPosition" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"duration" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"fileSizeInBytes" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"title" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"thumbnailTimeouted" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"unread" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"albumTrackNumber" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"album" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"artist" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"genre" options:0 context:nil];
[(MLFile*)_mediaObject willDisplay];
}
[self _addObserver];
}
[self _updatedDisplayedInformationForKeyPath:nil];
......
......@@ -26,6 +26,11 @@
@implementation VLCPlaylistTableViewCell
- (void)dealloc
{
[self _removeObserver];
}
+ (VLCPlaylistTableViewCell *)cellWithReuseIdentifier:(NSString *)ident
{
NSArray *nibContentArray;
......@@ -46,68 +51,78 @@
[self _updatedDisplayedInformationForKeyPath:keyPath];
}
- (void)_removeObserver
{
if ([_mediaObject isKindOfClass:[MLLabel class]]) {
[_mediaObject removeObserver:self forKeyPath:@"files"];
[_mediaObject removeObserver:self forKeyPath:@"name"];
} else if ([_mediaObject isKindOfClass:[MLShow class]])
[_mediaObject removeObserver:self forKeyPath:@"episodes"];
else if ([_mediaObject isKindOfClass:[MLShowEpisode class]]) {
[_mediaObject removeObserver:self forKeyPath:@"name"];
[_mediaObject removeObserver:self forKeyPath:@"files"];
[_mediaObject removeObserver:self forKeyPath:@"artworkURL"];
[_mediaObject removeObserver:self forKeyPath:@"unread"];
} else if ([_mediaObject isKindOfClass:[MLAlbum class]]) {
[_mediaObject removeObserver:self forKeyPath:@"name"];
[_mediaObject removeObserver:self forKeyPath:@"tracks"];
} else if ([_mediaObject isKindOfClass:[MLFile class]]) {
[_mediaObject removeObserver:self forKeyPath:@"computedThumbnail"];
[_mediaObject removeObserver:self forKeyPath:@"lastPosition"];
[_mediaObject removeObserver:self forKeyPath:@"duration"];
[_mediaObject removeObserver:self forKeyPath:@"fileSizeInBytes"];
[_mediaObject removeObserver:self forKeyPath:@"title"];
[_mediaObject removeObserver:self forKeyPath:@"thumbnailTimeouted"];
[_mediaObject removeObserver:self forKeyPath:@"unread"];
[_mediaObject removeObserver:self forKeyPath:@"albumTrackNumber"];
[_mediaObject removeObserver:self forKeyPath:@"album"];
[_mediaObject removeObserver:self forKeyPath:@"artist"];
[_mediaObject removeObserver:self forKeyPath:@"genre"];
[(MLFile*)_mediaObject didHide];
}
}
- (void)_addObserver
{
if ([_mediaObject isKindOfClass:[MLLabel class]]) {
[_mediaObject addObserver:self forKeyPath:@"files" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"name" options:0 context:nil];
} else if ([_mediaObject isKindOfClass:[MLShow class]])
[_mediaObject addObserver:self forKeyPath:@"episodes" options:0 context:nil];
else if ([_mediaObject isKindOfClass:[MLShowEpisode class]]) {
[_mediaObject addObserver:self forKeyPath:@"name" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"files" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"artworkURL" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"unread" options:0 context:nil];
} else if ([_mediaObject isKindOfClass:[MLAlbum class]]) {
[_mediaObject addObserver:self forKeyPath:@"name" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"tracks" options:0 context:nil];
} else if ([_mediaObject isKindOfClass:[MLFile class]]) {
[_mediaObject addObserver:self forKeyPath:@"computedThumbnail" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"lastPosition" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"duration" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"fileSizeInBytes" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"title" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"thumbnailTimeouted" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"unread" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"albumTrackNumber" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"album" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"artist" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"genre" options:0 context:nil];
[(MLFile*)_mediaObject willDisplay];
}
}
- (void)setMediaObject:(MLFile *)mediaObject
{
if (_mediaObject != mediaObject) {
if ([_mediaObject isKindOfClass:[MLLabel class]]) {
[_mediaObject removeObserver:self forKeyPath:@"files"];
[_mediaObject removeObserver:self forKeyPath:@"name"];
} else if ([_mediaObject isKindOfClass:[MLShow class]])
[_mediaObject removeObserver:self forKeyPath:@"episodes"];
else if ([_mediaObject isKindOfClass:[MLShowEpisode class]]) {
[_mediaObject removeObserver:self forKeyPath:@"name"];
[_mediaObject removeObserver:self forKeyPath:@"files"];
[_mediaObject removeObserver:self forKeyPath:@"artworkURL"];
[_mediaObject removeObserver:self forKeyPath:@"unread"];
} else if ([_mediaObject isKindOfClass:[MLAlbum class]]) {
[_mediaObject removeObserver:self forKeyPath:@"name"];
[_mediaObject removeObserver:self forKeyPath:@"tracks"];
} else if ([_mediaObject isKindOfClass:[MLFile class]]) {
[_mediaObject removeObserver:self forKeyPath:@"computedThumbnail"];
[_mediaObject removeObserver:self forKeyPath:@"lastPosition"];
[_mediaObject removeObserver:self forKeyPath:@"duration"];
[_mediaObject removeObserver:self forKeyPath:@"fileSizeInBytes"];
[_mediaObject removeObserver:self forKeyPath:@"title"];
[_mediaObject removeObserver:self forKeyPath:@"thumbnailTimeouted"];
[_mediaObject removeObserver:self forKeyPath:@"unread"];
[_mediaObject removeObserver:self forKeyPath:@"albumTrackNumber"];
[_mediaObject removeObserver:self forKeyPath:@"album"];
[_mediaObject removeObserver:self forKeyPath:@"artist"];
[_mediaObject removeObserver:self forKeyPath:@"genre"];
[(MLFile*)_mediaObject didHide];
}
[self _removeObserver];
_mediaObject = mediaObject;
// prevent the cell from recycling the current snap for random contents
self.thumbnailView.image = nil;
if ([_mediaObject isKindOfClass:[MLLabel class]]) {
[_mediaObject addObserver:self forKeyPath:@"files" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"name" options:0 context:nil];
} else if ([_mediaObject isKindOfClass:[MLShow class]])
[_mediaObject addObserver:self forKeyPath:@"episodes" options:0 context:nil];
else if ([_mediaObject isKindOfClass:[MLShowEpisode class]]) {
[_mediaObject addObserver:self forKeyPath:@"name" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"files" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"artworkURL" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"unread" options:0 context:nil];
} else if ([_mediaObject isKindOfClass:[MLAlbum class]]) {
[_mediaObject addObserver:self forKeyPath:@"name" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"tracks" options:0 context:nil];
} else if ([_mediaObject isKindOfClass:[MLFile class]]) {
[_mediaObject addObserver:self forKeyPath:@"computedThumbnail" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"lastPosition" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"duration" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"fileSizeInBytes" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"title" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"thumbnailTimeouted" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"unread" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"albumTrackNumber" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"album" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"artist" options:0 context:nil];
[_mediaObject addObserver:self forKeyPath:@"genre" options:0 context:nil];
[(MLFile*)_mediaObject willDisplay];
}
[self _addObserver];
}
[self _updatedDisplayedInformationForKeyPath:nil];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment