【问题标题】:Duplicate data added to REALM once view loaded加载视图后将重复数据添加到 REALM
【发布时间】:2015-11-26 03:48:28
【问题描述】:

我有一个小问题,每次我从细节视图控制器回到主视图控制器时,我都会将重复的数据添加到 REALM 数据库中。我还尝试替换 viewDidLoad 中的网络代码,但我收到此错误 * Terminating app due to uncaught exception 'RLMException', reason: 'Index 2 is out of bounds*. 下面是我的代码:

#import "HomeTVC.h"
#import "facebook.h"
#import "HomeTVCell.h"
#import "MBProgressHUD.h"
#import "PageVideosCVC.h"
#import "HomePageList.h"
#import <SDWebImage/UIImageView+WebCache.h>

@interface HomeTVC ()<UITableViewDataSource, UITableViewDelegate>
{
    NSDictionary *userPageLikesParams;
    NSMutableArray *pagesInfo;
    NSArray *pagesInfoFromRealm;
    facebook *fb;
    HomePageList *homePageList;

}
@end

@implementation HomeTVC

- (void) viewDidAppear:(BOOL)animated {

    [super viewDidAppear:YES];

    // Add HUD
    [MBProgressHUD showHUDAddedTo:self.view animated:YES];

    userPageLikesParams = @{@"fields": @"about,name,created_time,picture",@"limit": @"10"} ;

    fb = [[facebook alloc] init];

    [fb getUserPagelikes:userPageLikesParams completionHandler:^(NSDictionary *pagesResult) {

        if (pagesResult != nil) {

            [pagesInfo addObjectsFromArray:[pagesResult valueForKeyPath:@"data"]];

            //           pagesInfo = pagesResult[@"data"];

            // Delete all available data in REALM

            RLMRealm *realm = [RLMRealm defaultRealm];
            [realm beginWriteTransaction];
            [realm deleteAllObjects];
            [realm commitWriteTransaction];

            [realm beginWriteTransaction];
            for(NSDictionary *pageInfoToSaveInRealm in pagesInfo){
                HomePageList *homePages = [[HomePageList alloc] init];
                homePages.pageID = pageInfoToSaveInRealm[@"id"];
                homePages.pageName = pageInfoToSaveInRealm[@"name"];
                homePages.pageProfilePic = [pageInfoToSaveInRealm valueForKeyPath:@"picture.data.url"];
                [realm addObject:homePages];

                dispatch_async(dispatch_get_main_queue(), ^{
                    RLMRealm *realmMainThread = [RLMRealm defaultRealm];
                    RLMResults *pagesInformation = [HomePageList allObjectsInRealm:realmMainThread];
                    pagesInfoFromRealm = pagesInformation;
                    NSLog(@"ayam : %d", (int)pagesInfoFromRealm.count);

                    [self.tableView reloadData];
                    [MBProgressHUD hideHUDForView:self.view animated:YES];
                });

            }
            [realm commitWriteTransaction];

        }

    } failure:^(NSError *error) {
        if(error) {
            pagesInfoFromRealm = [HomePageList allObjects];
            [self.tableView reloadData];
            [MBProgressHUD hideHUDForView:self.view animated:YES];
        }
    }];

    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}


- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.delegate = self;
    self.tableView.dataSource = self;

    pagesInfo = [NSMutableArray array];

    // [facebook currentFBAccessToken];
    // [facebook getFBUserInfo];

}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (pagesInfoFromRealm == nil) {
        return 0;
    } else {
        NSLog(@"table count : %d", (int)pagesInfoFromRealm.count);
        return pagesInfoFromRealm.count;
    }

}


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

    static NSString *CellIdentifier = @"CellIdentifier";

    HomeTVCell *cell = (HomeTVCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    //  NSLog(@"pagesInfoFromRealm : %@", pagesInfoFromRealm);

    homePageList = pagesInfoFromRealm[[indexPath item]];

    NSURL *imageURL = [NSURL URLWithString:homePageList.pageProfilePic];

    // cache the image using sdwebimage
    cell.pageProfilePic.layer.backgroundColor=[[UIColor clearColor] CGColor];
    cell.pageProfilePic.layer.borderWidth = 2.0;
    cell.pageProfilePic.layer.masksToBounds = YES;
    cell.pageProfilePic.layer.borderColor=[[UIColor whiteColor] CGColor];
    cell.pageProfilePic.layer.cornerRadius= 30.0;
    [cell.pageProfilePic sd_setImageWithURL:imageURL placeholderImage:[UIImage imageNamed:@"placeholder.jpg"]];
    cell.pageName.text = homePageList.pageName;

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UIStoryboard*  sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    PageVideosCVC *pageVideo = [sb instantiateViewControllerWithIdentifier:@"videoDetails"];
    homePageList = pagesInfoFromRealm[indexPath.row];
    NSLog(@"pagesInfoFromRealm array count: %d", (int)pagesInfoFromRealm.count);

    NSLog(@"homepagelist data: %@", pagesInfoFromRealm[indexPath.row]);
    pageVideo.pageID = homePageList[@"pageID"];
    pageVideo.pageName = homePageList[@"pageName"];
    [self presentViewController:pageVideo animated:YES completion:nil];

}

@end

提前致谢。

【问题讨论】:

  • 将所有领域代码移动到自定义方法,例如(void)doAfterGetData 或其他东西,仅在您需要时调用它...这样您可以更好地控制它而不是放入viewdidappear

标签: ios objective-c uitableview xcode7 realm


【解决方案1】:

您在viewDidAppear: 中添加数据。每次视图显示时都会调用该方法。所以当用户从详细视图返回到这个视图时也会调用它。

相反,将其移至viewDidLoad 或将代码移至另一个方法并仅在需要时调用它。

如果您确实需要在您的viewDidAppear 中包含该代码,并且假设您已将pageId 标记为HomePageList 的主键,您可以使用addOrUpdateObject: 而不是addObject:。这将确保如果对象已经存在于 Realm 中,它只会更新而不是复制。

【讨论】:

    【解决方案2】:

    为确保只执行一次,您可以将操作移动到 isMovingToParent 检查,这是一种特殊的 BOOL 方法,只能在 UIViewController 转换期间使用:

    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
    
        if ( [self isMovingToParentViewController]) {
    
            // Action
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-10
      相关资源
      最近更新 更多