Note that there are some explanatory texts on larger screens.

plurals
  1. POVery jerky scrolling NSTableView
    primarykey
    data
    text
    <p>I have an NSScrollView which contains an NSTableView, this has 3 columns, 1 of which has a custom view in it via TableCellView.</p> <p>To load images into this cell via background processes, i have subclassed the cell using the below code. However the scrolling is really jerky, i am wondering if there is any way to optimise this, the images are not very large, 48x48, and are being displayed at 51x51.</p> <p>I suspect the fact that a fetch request is being used for each row is probably not very efficient, and i need to find a way to set an NSArray each time the view is changed that is current, and use that instead. But i was wanting to get this as efficient as possible first.</p> <pre><code>- (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:&amp;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; } </code></pre> <p>Thanks</p> <p>Gareth</p> <p><strong>EDIT 1</strong></p> <p>Ok have tried implementing AFImageRequest, and performance is worst, and also i seem to get getting multiple copies of the same image/the wrong image in various rows.</p> <p>Here is the code i am using.</p> <pre><code>@synthesize profileImage = _profileImage; + (NSOperationQueue *)sharedProfileImageRequestOperationQueue { static NSOperationQueue *_sharedProfileImageRequestOperationQueue = nil; static dispatch_once_t onceToken; dispatch_once(&amp;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:&amp;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; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload