0

NSTableView を含む NSScrollView があります。これには 3 つの列があり、そのうちの 1 つには TableCellView を介したカスタム ビューがあります。

バックグラウンド プロセスを介してこのセルに画像を読み込むために、以下のコードを使用してセルをサブクラス化しました。ただし、スクロールは非常にぎくしゃくしています。これを最適化する方法があるかどうか疑問に思っています。画像は 48x48 とあまり大きくなく、51x51 で表示されています。

各行にフェッチ要求が使用されているという事実はおそらくあまり効率的ではないと思われます。ビューが変更されるたびに現在の NSArray を設定する方法を見つけ、代わりにそれを使用する必要があります。しかし、私は最初にこれをできるだけ効率的にしたいと思っていました。

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {

// Get a new ViewCell
NSTableCellView *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];

//Identify the correct column
if( [tableColumn.identifier isEqualToString:@"userLogo"] )
{

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


    //Set predicate and filter for New tweets page
    if ([self.currentTwitterView isEqualToString:@"new"]) {
        NSPredicate *testForTrue = [NSPredicate predicateWithFormat:@"(approved == NO) AND (tweetDeleted == NO)  AND (scheduledTweet == NO)"];
        NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"postDate" ascending:NO];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
        [request setPredicate:testForTrue];
        [request setSortDescriptors:sortDescriptors];

    //Set filter and predicate for the Approved tweets page
    } else if ([self.currentTwitterView isEqualToString:@"approved"]){
        NSPredicate *testForTrue = [NSPredicate predicateWithFormat:@"(approved == YES) AND (tweetDeleted == NO)  AND (scheduledTweet == NO)"];
        NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"approvedDate" ascending:NO];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
        [request setPredicate:testForTrue];
        [request setSortDescriptors:sortDescriptors];

    //Set filter and preicate for the Deleted tweets page
    } else if ([self.currentTwitterView isEqualToString:@"deleted"]){
        NSPredicate *testForTrue = [NSPredicate predicateWithFormat:@"tweetDeleted == YES"];
        NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"deletedDate" ascending:NO];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
        [request setPredicate:testForTrue];
        [request setSortDescriptors:sortDescriptors];

    //Set filter and preicate for the Deleted tweets page
    } else if ([self.currentTwitterView isEqualToString:@"scheduled"]){
    NSPredicate *testForTrue = [NSPredicate predicateWithFormat:@"scheduledTweet == YES"];
    NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"scheduledDate" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
    [request setPredicate:testForTrue];
    [request setSortDescriptors:sortDescriptors];
    }


    //Setup the Request
    [request setEntity:[NSEntityDescription entityForName:@"Tweet" inManagedObjectContext:_managedObjectContext]];

    //Assign the predicate to the fetch request
    NSError *error = nil;

    //Create an array from the returned objects
    NSArray *fetchedObjects = [_managedObjectContext executeFetchRequest:request error:&error];

    Tweet *selectedTweet = [fetchedObjects objectAtIndex:row];

    cellView.imageView.image = nil;
    dispatch_async(dispatch_queue_create("getAsynchronIconsGDQueue", NULL),
                   ^{
                       NSURL *url = [NSURL URLWithString:selectedTweet.avatarUrl];
                       NSImage *image = [[NSImage alloc] initWithContentsOfURL:url];
                       cellView.imageView.image = image;
                   });
    [cellView setWantsLayer:YES];
    return cellView;
     }

    [cellView setWantsLayer:YES];
    return cellView;
}

ありがとう

ガレス

編集1

OK、AFImageRequest を実装しようとしましたが、パフォーマンスが最悪です。また、同じ画像の複数のコピー/間違った画像をさまざまな行に取得しているようです。

これが私が使用しているコードです。

@synthesize profileImage = _profileImage;

+ (NSOperationQueue *)sharedProfileImageRequestOperationQueue {
static NSOperationQueue *_sharedProfileImageRequestOperationQueue = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    _sharedProfileImageRequestOperationQueue = [[NSOperationQueue alloc] init];
    [_sharedProfileImageRequestOperationQueue setMaxConcurrentOperationCount:8];
});

return _sharedProfileImageRequestOperationQueue;
}

//Load the image into the table

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {

// Get a new ViewCell
NSTableCellView *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];

//Identify the correct column
if( [tableColumn.identifier isEqualToString:@"userLogo"] )
{

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


    //Set predicate and filter for New tweets page
    if ([self.currentTwitterView isEqualToString:@"new"]) {
        NSPredicate *testForTrue = [NSPredicate predicateWithFormat:@"(approved == NO) AND (tweetDeleted == NO)  AND (scheduledTweet == NO)"];
        NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"postDate" ascending:NO];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
        [request setPredicate:testForTrue];
        [request setSortDescriptors:sortDescriptors];

    //Set filter and predicate for the Approved tweets page
    } else if ([self.currentTwitterView isEqualToString:@"approved"]){
        NSPredicate *testForTrue = [NSPredicate predicateWithFormat:@"(approved == YES) AND (tweetDeleted == NO)  AND (scheduledTweet == NO)"];
        NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"approvedDate" ascending:NO];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
        [request setPredicate:testForTrue];
        [request setSortDescriptors:sortDescriptors];

    //Set filter and preicate for the Deleted tweets page
    } else if ([self.currentTwitterView isEqualToString:@"deleted"]){
        NSPredicate *testForTrue = [NSPredicate predicateWithFormat:@"tweetDeleted == YES"];
        NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"deletedDate" ascending:NO];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
        [request setPredicate:testForTrue];
        [request setSortDescriptors:sortDescriptors];

    //Set filter and preicate for the Deleted tweets page
    } else if ([self.currentTwitterView isEqualToString:@"scheduled"]){
    NSPredicate *testForTrue = [NSPredicate predicateWithFormat:@"scheduledTweet == YES"];
    NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"scheduledDate" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
    [request setPredicate:testForTrue];
    [request setSortDescriptors:sortDescriptors];
    }


    //Setup the Request
    [request setEntity:[NSEntityDescription entityForName:@"Tweet" inManagedObjectContext:_managedObjectContext]];

    //Assign the predicate to the fetch request
    NSError *error = nil;

    //Create an array from the returned objects
    NSArray *fetchedObjects = [_managedObjectContext executeFetchRequest:request error:&error];

    Tweet *selectedTweet = [fetchedObjects objectAtIndex:row];

    NSURL *url = [NSURL URLWithString:selectedTweet.avatarUrl];

    /*cellView.imageView.image = nil;
    dispatch_async(dispatch_queue_create("getAsynchronIconsGDQueue", NULL),
                   ^{
                       NSURL *url = [NSURL URLWithString:selectedTweet.avatarUrl];
                       NSImage *image = [[NSImage alloc] initWithContentsOfURL:url];
                       cellView.imageView.image = image;
                   });

     */

     _avatarImageRequestOperation = [AFImageRequestOperation imageRequestOperationWithRequest:[NSURLRequest requestWithURL:url] success:^(NSImage *image) {
     cellView.imageView.image = self.profileImage;

     _avatarImageRequestOperation = nil;

     [[NSNotificationCenter defaultCenter] postNotificationName:kUserProfileImageDidLoadNotification object:self userInfo:nil];
     }];

     [_avatarImageRequestOperation setCacheResponseBlock:^NSCachedURLResponse *(NSURLConnection *connection, NSCachedURLResponse *cachedResponse) {
     return [[NSCachedURLResponse alloc] initWithResponse:cachedResponse.response data:cachedResponse.data userInfo:cachedResponse.userInfo storagePolicy:NSURLCacheStorageAllowed];
     }];

     [[[self class] sharedProfileImageRequestOperationQueue] addOperation:_avatarImageRequestOperation];

    //cellView.imageView.image = self.profileImage;

    //[cellView setWantsLayer:YES];
    return cellView;

}
4

2 に答える 2

0

いくつかのことが頭に浮かびます:

  1. 現在、ネットワークをスラッシングしています。キャッシングはなく、セルがロードされるたびにネットワークを実行して、おそらく既に存在するファイルを取得します。
  2. 画像検索のためにAFNetworkingを試しましたか? 特に快適な 'UIImageView+AFNetworking.h' カテゴリがあり、必要なことを正確に実行します。
  3. 以下をメインスレッドから移動しようとしましたか?

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

//Set predicate and filter for New tweets page
if ([self.currentTwitterView isEqualToString:@"new"]) {
    NSPredicate *testForTrue = [NSPredicate predicateWithFormat:@"(approved == NO) AND (tweetDeleted == NO)  AND (scheduledTweet == NO)"];
    NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"postDate" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
    [request setPredicate:testForTrue];
    [request setSortDescriptors:sortDescriptors];

//Set filter and predicate for the Approved tweets page
} else if ([self.currentTwitterView isEqualToString:@"approved"]){
    NSPredicate *testForTrue = [NSPredicate predicateWithFormat:@"(approved == YES) AND (tweetDeleted == NO)  AND (scheduledTweet == NO)"];
    NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"approvedDate" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
    [request setPredicate:testForTrue];
    [request setSortDescriptors:sortDescriptors];

//Set filter and preicate for the Deleted tweets page
} else if ([self.currentTwitterView isEqualToString:@"deleted"]){
    NSPredicate *testForTrue = [NSPredicate predicateWithFormat:@"tweetDeleted == YES"];
    NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"deletedDate" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
    [request setPredicate:testForTrue];
    [request setSortDescriptors:sortDescriptors];

//Set filter and preicate for the Deleted tweets page
} else if ([self.currentTwitterView isEqualToString:@"scheduled"]){
NSPredicate *testForTrue = [NSPredicate predicateWithFormat:@"scheduledTweet == YES"];
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"scheduledDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
[request setPredicate:testForTrue];
[request setSortDescriptors:sortDescriptors];
}


//Setup the Request
[request setEntity:[NSEntityDescription entityForName:@"Tweet" inManagedObjectContext:_managedObjectContext]];

//Assign the predicate to the fetch request
NSError *error = nil;

//Create an array from the returned objects
NSArray *fetchedObjects = [_managedObjectContext executeFetchRequest:request error:&error];

Tweet *selectedTweet = [fetchedObjects objectAtIndex:row];
于 2013-07-31T21:25:57.223 に答える
0

OK、さらにトラブルシューティングを行った後、画像を完全に削除しましたが、テーブルはまだ犬のように遅かったです。そのため、現在選択されているオブジェクトの配列を維持する新しい関数を作成して、すべての行に対して呼び出すテーブル描画関数を保存しました。これで問題は完全に修正され、すべてがバターのように滑らかで美しいものになりました.

したがって、フェッチ リクエストは非常にコストがかかるようです。

乾杯

ガレス

于 2013-08-01T13:48:48.040 に答える