RLMException-对象已被无效或删除

时间:2018-07-06 03:14:56

标签: objective-c oop exception realm bugsnag

我遇到RLM异常(可能访问RLMArray导致了它-https://realm.io/docs/objc/latest/api/Classes/RLMObject.html#/c:objc%28cs%29RLMObject%28py%29invalidated

对象已被删除或无效。

在Bugsnag上的崩溃日志如下:

2光束
RLMObject_Private.hpp:45:9 RLMVerifyAttached

3光束
ChatPeopleViewController.m:270:22 -[ChatPeopleViewController lastMessage:]

4光束
ChatPeopleViewController.m:223:30 -[ChatPeopleViewController tableView:cellForRowAtIndexPath:]

相关源代码:

#import "ChatPeopleViewController.h"
#import "UIImageView+WebCache.h"
#import "ChatPeopleCell.h"
#import "ClientManager.h"
#import "BeamString.h"
#import "ChatViewController.h"
#import "BMAddNewChatViewController.h"
#import "UIFont+Custom.h"
#import "UITabBarItem+CustomBadge.h"
#import "BMTableViewRowActionWithImage.h"
#import "Appirater.h"
#import "BMUserStatusManager.h"
#import "OnlineStatusResponse.h"
#import "NSDate+BMCustom.h"
#import "BMChatSession.h"
#import "BMGroupChatManager.h"
#import "BMGroupMember.h"
#import "BMGroupChatViewController.h"
#import "GroupChatPeopleCell.h"


static NSString * const kCellIdentifier = @"UserCell";
static NSString * const kGroupCellIdentifier = @"UserCell";

@interface ChatPeopleViewController ()<SWTableViewCellDelegate> {
    NSMutableArray *friends;
    NSArray *reverseChronoArray;
}

@end

@implementation ChatPeopleViewController
-(UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

-(instancetype)init
{
    self = [super init];
    if (self) {
        self.title = NSLocalizedString(@"Beam Chats", nil);
        [self customRightBarItem:@selector(btn_rightClicked:) image:[UIImage imageNamed:@"icon_recent"]];
//        [BeamAPI updateUserName:@"test2" complete:^(BOOL isSuccess, NSDictionary *responseObject, NSError *err){
//            if (isSuccess) {
//            }
//            // self.onlineIndicator.image = [UIImage imageNamed:@"presence_online"];
//        }];


    }
    return self;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.screenName = @"Chat list";

    [self registerCells];

    self.extendedLayoutIncludesOpaqueBars = YES;
    self.edgesForExtendedLayout = UIRectEdgeBottom|UIRectEdgeLeft|UIRectEdgeRight;

    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
    [self.tableView_chat addSubview:refreshControl];
    [refreshControl addTarget:self action:@selector(handlePullToRefresh:) forControlEvents:UIControlEventValueChanged];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(handleProfileUpdate:)
                                                 name:friendProfileDidUpdateNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(handleOnlineStatusUpdate:)
                                                 name:kUpdateOnlineStatusNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(updateBadgeCount:)
                                                 name:kUpdateBadgeCountNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(messageRetractedUpdate)
                                                 name:kRetractMessageNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(reloadForNotification:)
                                                 name:kChatViewControllerShouldRefreshNotification
                                               object:nil];
}

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    _tableView_chat.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
    _tableView_chat.contentInset = UIEdgeInsetsMake(0.0f,
                                                    0.0f,
                                                    [[AppDelegate sharedInstance] tabBarHeight],
                                                    0.0);

    [self sortReverseChronoArray];
    [self updateBadgeCount:nil];
}

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self.tableView_chat reloadData];
    [MBProgressHUD hideAllHUDsForView:self.tabBarController.view animated:YES];
}

-(void)btn_rightClicked:(id)sender
{

//    [BeamAPI sendMsgToBotWithVersion:1 scr:@"" cmd:@"" chn:@"" qid:@"" qry:@"" complete:^(BOOL isSuccess, id responseObject, NSError *err){
//    
//    
//    }];

//    NSArray *ary = [[BMGroupChatManager sharedManager] getMembersInGroup:@"13"];

//    [[BMGroupChatManager sharedManager] createNewGroupWithEmails:@[@"st85368@gmail.com",@"test2@test2.com"] complete:^(NSString *chatID){
//        //create group in realm;
//        [[ClientManager sharedManager] createDialoguesIfNeeded:chatID isGroup:YES];
//        
//        
//    }];

//    BMGroupMember *mem = [[BMGroupMember alloc] initWithString:@"test4@test4.com" topic:@"user/test4@test4.com"];
//    [[BMGroupChatManager sharedManager] addMemberToGroupChatID:mem chatID:@"30"];
//    [[BMGroupChatManager sharedManager] removeMembersFromGroupChatID:mem chatID:@"13"];

//    [BMGroupChatManager sharedManager].getAllGroupChats;

//    [BeamAPI getMemberInGroup:@"40" complete:^(BOOL isSuccess, id responseObject, NSError *err){
//        NSMutableArray * cityArray = [[NSMutableArray alloc] init];
//        NSMutableArray *jsonarry = responseObject[@"response"];
//        
//       // NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
//     //   NSMutableArray *testFeeds = [NSJSONSerialization JSONObjectWithData: data options:NSJSONReadingMutableContainers error:nil];
//       // [cityArray addObjectsFromArray:testFeeds];
//        
//    
//    }];


    BMAddNewChatViewController *vc = [[BMAddNewChatViewController alloc] init];
    vc.hidesBottomBarWhenPushed = YES;
    self.navigationItem.hidesBackButton = NO;
    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
    [self.navigationController pushViewController:vc animated:YES];
}

- (void)registerCells {
    [self.tableView_chat registerNib:[UINib nibWithNibName:@"ChatPeopleCell" bundle:nil]
         forCellReuseIdentifier:kCellIdentifier];
//    [self.tableView_chat registerClass: [GroupChatPeopleCell class] forCellReuseIdentifier:kGroupCellIdentifier];
}
- (void)registerNibWithTableView:(UITableView *)tableView{
    [self.tableView_chat registerNib:[UINib nibWithNibName:@"ChatPeopleCell" bundle:nil]
              forCellReuseIdentifier:kCellIdentifier];

}

#pragma mark - Table View Data source


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [reverseChronoArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    NSDictionary *emailAndHistoryDict = reverseChronoArray[indexPath.row];
    NSString *friendEmail = [emailAndHistoryDict allKeys][0];
    ChatPeopleCell *cell = [self.tableView_chat dequeueReusableCellWithIdentifier:kCellIdentifier];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    if ([[BMGroupChatManager sharedManager] isGroupChat: friendEmail]) {
        [cell loadUserDataForGroup:friendEmail];
    }else{
        [cell loadUserDataByEmail:friendEmail];
    }


    OnlineStatusResponse *userStatus = [[BMUserStatusManager sharedInstance] getUserStatus:friendEmail];

    if ([friendEmail isEqualToString:kBeamBotEmail]) {
        cell.onlineIndicator.image = [UIImage imageNamed:@"presence_online"];
    }else if (userStatus.isOnline) {
        cell.onlineIndicator.image = [UIImage imageNamed:@"presence_online"];
    }else{
        cell.onlineIndicator.image = [UIImage imageNamed:@"presence_offline"];
    }

    NSUInteger counter = [[ClientManager sharedManager] badgeCountForUser:friendEmail];
    if (counter == 0) {
        [cell.badgeButton setHidden:YES];
    }
    else{
        [cell.badgeButton setHidden:NO];
        [cell.badgeButton setTitle:[@(counter) stringValue] forState:UIControlStateNormal];
    }

    NSArray *historyMessages = emailAndHistoryDict[friendEmail];
    BeamString *lastString = [self lastMessage:historyMessages];
    if (lastString) {
        NSDate *date = [lastString timestampThatWorks];
        cell.timeLabel.text = [date timestampFormat];

        cell.statusLabel.textColor = UIColorFromRGB(0x6d6d6d);
        if ([lastString isImage]) {
            cell.statusLabel.text = NSLocalizedString(@"- Image -", nil);
        }else if(lastString.msgType == MSG_TYPE_STICKER){
            cell.statusLabel.text = NSLocalizedString(@"- Sticker -", nil);
        }else if (lastString.msgType == MSG_TYPE_SMILEYSTICKER){
            cell.statusLabel.text = NSLocalizedString(@"- Smiley -", nil);
        }else {
            cell.statusLabel.attributedText =  [self getAttrStrWithEmoji:[lastString string] isBlack:YES];
        }

        [cell displayReadImage:(lastString.isMine && (lastString.msgStatus == MSG_READ))
                     delivered:(lastString.isMine && (lastString.msgStatus == MSG_SENT))];
        cell.hidden = NO;
    }
    else {
        cell.statusLabel.text = NSLocalizedString(@"(no history available)", nil);
        cell.hidden = YES;
    }
    cell.clipsToBounds = YES;
        NSMutableArray *rightUtilityButtons = [NSMutableArray new];

    if (![self isFriend:friendEmail]) {
        //if his not a friend then add the option
        [rightUtilityButtons sw_addUtilityButtonWithColor:
         [UIColor whiteColor]
                                                     icon:[UIImage imageNamed:@"icon_contacts"]];
    }
    [rightUtilityButtons sw_addUtilityButtonWithColor:
     [UIColor whiteColor]
                                                 icon:[UIImage imageNamed:@"chat_cell_delete"]];

    cell.rightUtilityButtons = rightUtilityButtons;
    //    cell.leftUtilityButtons = [self leftButton];
    cell.delegate = self;
    return cell;
}

- (BeamString *)lastMessage:(NSArray *)messages {
    if (messages) {
        for (int i = (int)([messages count] - 1); i >= 0; i--) {
            BeamString *beam = messages[i];
            if (beam.string && beam.string.length > 0) {
                return beam;
            }
        }
    }
    return nil;
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 80;
}


#pragma mark -SWTableViewDelegate
- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index {
    NSIndexPath *cellIndexPath = [self.tableView_chat indexPathForCell:cell];
    NSDictionary *emailAndHistoryDict = reverseChronoArray[cellIndexPath.row];
    NSString *friendEmail = [emailAndHistoryDict allKeys][0];

    switch (index) {
        case 0:
            if (![self isFriend:friendEmail]) {
                [self addFriend:friendEmail withTableView:self.tableView_chat];
                [self.tableView_chat reloadData];
            }

            [self deleteChat:cellIndexPath];
            break;
        case 1:
        {

            [self deleteChat:cellIndexPath];

            break;
        }
        default:
            break;
    }
}
- (BOOL)swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:(SWTableViewCell *)cell{
    return YES;
}


#pragma mark - helpers

- (BOOL) isFriend:(NSString *)email{
    if (![[BMUserManager sharedInstance] isFriend:email] && ![email isEqualToString:kBeamBotEmail]) {
        return NO;
    }
    return YES;
}
- (void)addFriend:(NSString *)friendEmail withTableView:(UITableView *)tableView
{
    [[BMUserManager sharedInstance] addFriend:friendEmail];
    [tableView setEditing:NO animated:YES];

    UIAlertController *controller = [UIAlertController alertControllerWithTitle:nil
                                                                        message:NSLocalizedString(@"Added friend", nil)
                                                                 preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *action = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
                                                     style:UIAlertActionStyleDefault
                                                   handler:nil];
    [controller addAction:action];
    [self presentViewController:controller animated:YES completion:nil];
}

- (void)deleteChat:(NSIndexPath *)indexPath
{
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Confirm", nil)
                                                                   message:NSLocalizedString(@"Are you sure want to delete this conversation?", nil)
                                                            preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *delete = [UIAlertAction actionWithTitle:NSLocalizedString(@"Delete", nil)
                                                     style:UIAlertActionStyleDestructive
                                                   handler:^(UIAlertAction * _Nonnull action) {
                                                       NSDictionary *emailAndHistoryDict = reverseChronoArray[indexPath.row];
                                                       NSString *friend = [emailAndHistoryDict allKeys][0];
                                                       NSMutableDictionary *messageDict = [ClientManager sharedManager].chatSessions;
                                                       [messageDict removeObjectForKey:friend];

                                                       //delete realm record
                                                       [[ClientManager sharedManager] deleteDialogues:friend];

                                                       NSMutableArray *array = [reverseChronoArray mutableCopy];
                                                       [array removeObjectAtIndex:indexPath.row];
                                                       reverseChronoArray = array;
                                                       [self.tableView_chat deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

                                                       self.noChatsMessage.hidden = ([reverseChronoArray count] > 0);
                                                   }];
    UIAlertAction *keep = [UIAlertAction actionWithTitle:NSLocalizedString(@"Keep", nil)
                                                   style:UIAlertActionStyleCancel
                                                 handler:^(UIAlertAction * _Nonnull action) {}];
    [alert addAction:delete];
    [alert addAction:keep];
    [self presentViewController:alert animated:YES completion:^{}];
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *emailAndHistoryDict = reverseChronoArray[indexPath.row];

    NSString *friend = [emailAndHistoryDict allKeys][0];
    if (friend == nil) {
        return;
    }

    [BMUserManager sharedInstance].currentChatEmail = friend;
    [ClientManager sharedManager].currentFriend = friend;

    if (![friend isEqualToString:kBeamBotEmail]) {
        [Appirater userDidSignificantEvent:NO];
    }
    ChatViewController *vc ;
    if ([ClientManager sharedManager].curChatSession.isGroup) {
        vc = [[BMGroupChatViewController alloc] init];
        [[BMGroupChatManager sharedManager] updateGroupMembersForGroupID:friend];
        BMGroupChat *gc = [[BMGroupChatManager sharedManager] getGroupChatByID:friend];
        ((BMGroupChatViewController *)vc).groupChat = gc;
    }else{
        vc = [[ChatViewController alloc] init];
    }

    vc.hidesBottomBarWhenPushed = YES;

    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];

    self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
    [self.navigationController pushViewController:vc animated:YES];
}

-(void)viewDidLayoutSubviews
{
    if ([self.tableView_chat respondsToSelector:@selector(setSeparatorInset:)]) {
        [self.tableView_chat setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([self.tableView_chat respondsToSelector:@selector(setLayoutMargins:)]) {
        [self.tableView_chat setLayoutMargins:UIEdgeInsetsZero];
    }
}

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}


- (void)messageRetractedUpdate{
    [self.tableView_chat reloadData];
}

- (void)updateBadgeCount:(NSNotification *)note {

    [self sortReverseChronoArray];
    self.noChatsMessage.hidden = ([reverseChronoArray count] > 0);

    [self.tableView_chat reloadData];
    NSUInteger totBadge = [[ClientManager sharedManager] totalBadgeCount];
    if (totBadge > 0) {
        [self.navigationController.tabBarItem setCustomBadgeValue:@(totBadge).stringValue
                                                         withFont:[UIFont customAppFontOfSize:11.0]
                                                     andFontColor:[UIColor whiteColor]
                                               andBackgroundColor:BEAM_RED];
    }
    else{
        self.navigationController.tabBarItem.badgeValue = nil;
    }
}

- (void)reloadForNotification:(NSNotification *)note {
    [self sortReverseChronoArray];
    self.noChatsMessage.hidden = ([reverseChronoArray count] > 0);

    [self.tableView_chat reloadData];

}

#pragma mark - helpers

- (void)sortReverseChronoArray {
    //sort it reverse chronologically
    NSMutableArray *lastBeamStringsForUsers = [NSMutableArray array];

    for ( NSString *key in [ClientManager sharedManager].chatSessions) {
        NSArray* tmp =[[ClientManager sharedManager].chatSessions allKeys];
        if ([tmp count] > 0) {
            BMChatSession *cs = [ClientManager sharedManager].chatSessions[key];
            [lastBeamStringsForUsers  addObject: @{ key:cs.beamStrings}];
        }
    }
    reverseChronoArray = [lastBeamStringsForUsers sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *beamString1, NSDictionary *beamString2) {

        BeamString *friendStrings =  [[[beamString1 objectEnumerator] nextObject] lastObject]; //[beamString1[friendEmail1] lastObject];
        BeamString *friendStrings2 = [[[beamString2 objectEnumerator] nextObject] lastObject];
        if (!friendStrings2 || friendStrings2.invalidated) {
            return -1;
        }else if (!friendStrings || friendStrings.invalidated){
            return nil;
        }
        return [[friendStrings timestampThatWorks] compare:[friendStrings2 timestampThatWorks]] * -1;
    }];

}

- (void)handleProfileUpdate:(NSNotification *)note {
    NSString *email = [note object];
    if (![email isKindOfClass:[NSString class]]) {
        return;
    }
    for (ChatPeopleCell *cell in [self.tableView_chat visibleCells]) {
        if ([cell.loadedEmail isEqualToString:email]) {
            [cell loadUserDataByEmail:email];
        }
    }
}

- (NSMutableAttributedString *) getAttrStrWithEmoji:(NSString *)str isBlack:(BOOL)isBlack{
    NSString *orgStr = str;
    NSDictionary *attrs = @{ NSForegroundColorAttributeName : [UIColor whiteColor]};

    if (isBlack) {
        attrs = @{ NSForegroundColorAttributeName : [UIColor grayColor] };
    }

    NSMutableAttributedString *myString = [[NSMutableAttributedString alloc]initWithString:@"" attributes:attrs];

    //NSMutableAttributedString *myString = [[NSMutableAttributedString alloc]init];
    NSAttributedString *attachmentString;
    NSString *regEx = @"\\[A[0-9]{2}]";

    while (orgStr.length > 0) {
        NSRange range = [orgStr rangeOfString:regEx options:NSRegularExpressionSearch];
        if (range.location != NSNotFound) {
            NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
            NSRange imageNameRange = NSMakeRange(range.location + 1, range.length - 2);


            NSString *imageFile =[NSString stringWithFormat:@"%@",[orgStr substringWithRange:imageNameRange]];

            NSString *firstPartStr = [orgStr substringToIndex:range.location];
            NSAttributedString *firstPartAttStr = [[NSAttributedString alloc] initWithString:firstPartStr attributes:attrs];
            [myString appendAttributedString:firstPartAttStr];


            orgStr = [orgStr substringFromIndex:(range.location + range.length)];
            UIImage *emoji = [UIImage reSizeImage:[UIImage imageNamed:imageFile] toSize:CGSizeMake(15.5, 15.5)];
            attachment.image =  emoji;


            attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];
            [myString appendAttributedString:attachmentString];
        }
        else{

            NSAttributedString *lastPartAttStr = [[NSAttributedString alloc] initWithString:orgStr attributes:attrs];

            [myString appendAttributedString:lastPartAttStr];

            break;
        }
    }
    return myString;
}

- (void)handlePullToRefresh:(UIRefreshControl *)sender {
    [sender performSelector:@selector(endRefreshing) withObject:nil afterDelay:1.2];
}

- (void)handleOnlineStatusUpdate:(NSNotification *)note {
    NSSet *emails = [note object];
    for (NSString *email in emails){
        if (![email isKindOfClass:[NSString class]]) {
            return;
        }
        for (ChatPeopleCell *cell in [self.tableView_chat visibleCells]) {
            if ([email isEqualToString:kBeamBotEmail]) {
                cell.onlineIndicator.image = cell.onlineIndicator.image = [UIImage imageNamed:@"presence_online"];
            }else if ([cell.loadedEmail isEqualToString:email]) {
                OnlineStatusResponse *userStatus = [[BMUserStatusManager sharedInstance] getUserStatus:email];
                if (userStatus.isOnline) {
                    cell.onlineIndicator.image = [UIImage imageNamed:@"presence_online"];
                }else{
                    cell.onlineIndicator.image = [UIImage imageNamed:@"presence_offline"];
                }
            }
        }
    }
}




@end

请检查。

0 个答案:

没有答案