Fix a crash in feedback list view with attachments

The crash was happening when an attachment was still loading in the last cell but before loading ended, the number of cells changed by deleting a message. Once the attachment was loaded, the crash occured.

This is no fixed by using a safer approach on updating the cell content for loaded attachments by using notifications and letting the cells decide themselves if they need to re-display their content.
This commit is contained in:
Andreas Linde
2015-02-19 15:05:03 +01:00
parent 5c5c8a9a5e
commit 30375a0362
4 changed files with 49 additions and 1 deletions

View File

@@ -26,11 +26,13 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#import "HockeySDK.h"
#import "HockeySDKPrivate.h"
#import "BITFeedbackListViewCell.h"
#import "BITFeedbackMessageAttachment.h"
#import "BITActivityIndicatorButton.h"
#import "BITFeedbackManagerPrivate.h"
#define BACKGROUNDCOLOR_DEFAULT BIT_RGBCOLOR(245, 245, 245)
#define BACKGROUNDCOLOR_ALTERNATE BIT_RGBCOLOR(235, 235, 235)
@@ -70,6 +72,8 @@
@property (nonatomic, strong) UIView *accessoryBackgroundView;
@property (nonatomic, strong) id updateAttachmentNotification;
@end
@@ -107,13 +111,53 @@
_labelText.dataDetectorTypes = UIDataDetectorTypeAll;
_attachmentViews = [NSMutableArray new];
[self registerObservers];
}
return self;
}
- (void)dealloc {
[self unregisterObservers];
}
#pragma mark - Private
- (void) registerObservers {
__weak typeof(self) weakSelf = self;
if (nil == _updateAttachmentNotification) {
_updateAttachmentNotification = [[NSNotificationCenter defaultCenter] addObserverForName:kBITFeedbackUpdateAttachmentThumbnail
object:nil
queue:NSOperationQueue.mainQueue
usingBlock:^(NSNotification *note) {
typeof(self) strongSelf = weakSelf;
[strongSelf updateAttachmentFromNotification:note];
}];
}
}
- (void) unregisterObservers {
if (_updateAttachmentNotification) {
[[NSNotificationCenter defaultCenter] removeObserver:_updateAttachmentNotification];
_updateAttachmentNotification = nil;
}
}
- (void) updateAttachmentFromNotification:(NSNotification *)note {
if (!self.message) return;
if (!self.message.attachments) return;
if (self.message.attachments.count == 0) return;
if (!note.object) return;
if (![note.object isKindOfClass:[BITFeedbackMessageAttachment class]]) return;
BITFeedbackMessageAttachment *attachment = (BITFeedbackMessageAttachment *)note.object;
if (![self.message.attachments containsObject:attachment]) return;
// The attachment is part of the message used for this cell, so lets update it.
[self setAttachments:self.message.previewableAttachments];
[self setNeedsLayout];
}
- (UIColor *)backgroundColor {
if (self.backgroundStyle == BITFeedbackListViewCellBackgroundStyleNormal) {

View File

@@ -652,7 +652,7 @@
if (responseData.length) {
dispatch_async(dispatch_get_main_queue(), ^{
[attachment replaceData:responseData];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[[NSNotificationCenter defaultCenter] postNotificationName:kBITFeedbackUpdateAttachmentThumbnail object:attachment];
[[BITHockeyManager sharedHockeyManager].feedbackManager saveMessages];
});
}

View File

@@ -53,6 +53,8 @@
#define kBITFeedbackLastMessageID @"HockeyFeedbackLastMessageID"
#define kBITFeedbackAppID @"HockeyFeedbackAppID"
NSString *const kBITFeedbackUpdateAttachmentThumbnail = @"BITFeedbackUpdateAttachmentThumbnail";
@interface BITFeedbackManager()<UIGestureRecognizerDelegate>
@property (nonatomic, strong) UITapGestureRecognizer *tapRecognizer;

View File

@@ -30,6 +30,8 @@
#if HOCKEYSDK_FEATURE_FEEDBACK
extern NSString *const kBITFeedbackUpdateAttachmentThumbnail;
#import "BITFeedbackMessage.h"
@interface BITFeedbackManager () <UIAlertViewDelegate> {