我有一個NSScrollView包含一個NSTableView,它有3列,其中1個通過TableCellView有一個自定義視圖。非常生澀的滾動NSTableView
要通過後臺進程加載圖像到這個單元格,我已經使用下面的代碼子類化了單元格。然而,滾動是真的生澀,我想知道是否有任何方法來優化,圖像不是很大,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
好的嘗試實施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;
}
我沒有在這個看上去很仔細地(今衝),但想暗示什麼。在這種情況下,我傾向於使用後臺線程來加載前幾個(例如10個左右)圖像並將它們添加到表格視圖單元格中。然後我使用NSTimer每秒鐘加載幾次。這樣可以使起搏更多地展開。加載圖像後,我將它們緩存起來,以便將來可以更快地使用它們。你可能想考慮做類似的事情。如果有很多單元格,我也會最大限度地發揮它的功能。 – Josiah