0

多くUITableViewの行(+1000)があります。以下のようにand inUITableViewを使用して、これらの行を一度取得します。NSFetchedResultsControllerfetchBatchSizeviewDidLoad

@interface MessagesViewController ()  
@property (nonatomic, strong) NSFetchedResultsController *messagesFRC;
@end



@implementation MessagesViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    if (self.messagesFRC == nil) {

        // Read in Model.xcdatamodeld
        NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
        NSPersistentStoreCoordinator *psc =
        [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];

        // Where does the SQLite file go?
        NSArray *documentDirectories =
        NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                            NSUserDomainMask,
                                            YES);
        // Get one and only document directory from that list
        NSString *documentDirectory = [documentDirectories firstObject];
        NSString *path = [documentDirectory stringByAppendingPathComponent:@"model.sqlite"];

        NSURL *storeURL = [NSURL fileURLWithPath:path];
        NSError *error = nil;
        if (![psc addPersistentStoreWithType:NSSQLiteStoreType
                               configuration:nil
                                         URL:storeURL
                                     options:nil
                                       error:&error]) {
            @throw [NSException exceptionWithName:@"OpenFailure"
                                           reason:[error localizedDescription]
                                         userInfo:nil];
        }

        // Create the managed object context
        NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
        context.persistentStoreCoordinator = psc;

        NSFetchRequest *request = [[NSFetchRequest alloc] init];

        NSString *entityName = @"Message";
        NSString *sortAttribute = @"timestamp";


        NSEntityDescription *e = [NSEntityDescription entityForName:entityName
                                             inManagedObjectContext:context];

        request.entity = e;


        NSSortDescriptor *sd = [NSSortDescriptor
                                sortDescriptorWithKey:sortAttribute
                                ascending:NO];
        request.sortDescriptors = @[sd];

//        request.fetchLimit = 30;
        request.fetchBatchSize = 60;


        self.messagesFRC = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];


        NSError *error3 = nil;
        if (![self.messagesFRC performFetch:&error3]) {
            NSLog(@"Failed to initialize FetchedResultsController: %@\n%@", [error localizedDescription], [error userInfo]);
            abort();
        }

        self.messagesFRC.delegate = self;
    }
}

@end

heightForRowAtIndexPathまた、このコントローラーで各セルの高さを設定します。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{        
    if ([tableView isEqual:self.tableView]) {
        NSManagedObject *row = [self.messagesFRC objectAtIndexPath:indexPath];
        NSString *messageText = [[NSString alloc] initWithData:[row valueForKey:@"text"] encoding:NSUTF8StringEncoding];
        messageText = [[GeneralHelper convertHtmlToString:messageText] stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
        //        messageText = @"yes\r\nnew";

        NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
        paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
        paragraphStyle.alignment = NSTextAlignmentRight;
        //        paragraphStyle.


        NSDictionary *attributes = @{NSFontAttributeName: self.messageFont,
                                     NSParagraphStyleAttributeName: paragraphStyle}; // TODO: Font


        CGFloat width = CGRectGetWidth(tableView.frame)-kMessageTableViewCellAvatarHeight;
        width -= 25.0;

        CGRect titleBounds = [[row valueForKey:@"title"] boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:NULL];
        CGRect bodyBounds = [messageText boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:NULL];

        if (messageText.length == 0) {
            return 0.0;
        }

        CGFloat height = CGRectGetHeight(titleBounds);
        height += CGRectGetHeight(bodyBounds);
        height += 40.0;

        if (height < kMessageTableViewCellMinimumHeight) {
            height = kMessageTableViewCellMinimumHeight;
        }

        return height;
    }
    else {
        return kMessageTableViewCellMinimumHeight;
    }
}

問題は、ワークフローの開始時にすべてのセルの高さを設定するため、UITableView の読み込みに時間がかかる (15 秒以上) ことです。したがって、30 セルごとに遅延読み込みが必要heightForRowAtIndexPathであり、上下にスクロールして、次の 30 セルの高さを取得します。

さらに、UITableViewAutomaticDimensioniOS 7 以降を確認しましたが、CPU 使用率が非常に高かったです。

-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
   return UITableViewAutomaticDimension;
}

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

この問題を解決するには?

4

2 に答える 2

0

たぶん、セルのサイズを自動調整するようにしてください。

プロトタイプ セルに適切な制約を設定することで、メソッドを取り除くことができますheightForRowAtIndexPath

ドキュメントはこちらです。

于 2016-02-03T10:30:31.837 に答える
0

numberOfRenderedRows などのカウンターを使用できます。numberOfRenderedRows は最初に 30 に設定され、ユーザーがテーブルをスクロールして更新するたびに 30 ずつ追加されます。これは、テーブルビューの行数になります。以下を使用して、リフレッシュ コントロールを追加します。

#

UIRefreshControl* refreshControl = [[UIRefreshControl alloc]init];
[refreshControl addTarget:self action:@selector(actionRefreshRows) forControlEvents:UIControlEventValueChanged];
[tableView addSubview:refreshControl];
于 2016-02-03T10:10:52.247 に答える