Tôi đã viết hai cách để không đồng bộ tải ảnh bên trong ô UITableView của mình. Trong cả hai trường hợp, hình ảnh sẽ tải tốt nhưng khi tôi cuộn bảng, hình ảnh sẽ thay đổi một vài lần cho đến khi cuộn kết thúc và hình ảnh sẽ trở lại đúng hình ảnh. Tôi không biết tại sao điều này lại xảy ra.
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: [NSURL URLWithString:
@"http://myurl.com/getMovies.php"]];
[self performSelectorOnMainThread:@selector(fetchedData:)
withObject:data waitUntilDone:YES];
});
}
-(void)fetchedData:(NSData *)data
{
NSError* error;
myJson = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
[_myTableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// Return the number of rows in the section.
// Usually the number of items in your array (the one that holds your list)
NSLog(@"myJson count: %d",[myJson count]);
return [myJson count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
myCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (cell == nil) {
cell = [[myCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}
dispatch_async(kBgQueue, ^{
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://myurl.com/%@.jpg",[[myJson objectAtIndex:indexPath.row] objectForKey:@"movieId"]]]];
dispatch_async(dispatch_get_main_queue(), ^{
cell.poster.image = [UIImage imageWithData:imgData];
});
});
return cell;
}
... ...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
myCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (cell == nil) {
cell = [[myCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}
NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://myurl.com/%@.jpg",[[myJson objectAtIndex:indexPath.row] objectForKey:@"movieId"]]];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (!error){
cell.poster.image = [UIImage imageWithData:data];
// do whatever you want with image
}
}];
return cell;
}
poster
? Đó có lẽ là một hình ảnh trong ô tùy chỉnh của anh ấy, vì vậy những gì EXEC_BAD_ACCESS đang làm là hoàn toàn đúng. Bạn đúng rằng bạn không nên sử dụng ô làm kho lưu trữ dữ liệu mô hình, nhưng tôi không nghĩ đó là những gì anh ấy đang làm. Anh ta chỉ đưa ra tế bào tùy chỉnh những gì nó cần để trình bày. Hơn nữa, và đây là một vấn đề tinh tế hơn, tôi sẽ cảnh giác về việc lưu trữ một hình ảnh, trong mảng mô hình của bạn sao lưu bảng xem của bạn. Tốt hơn là sử dụng cơ chế lưu trữ hình ảnh và đối tượng mô hình của bạn sẽ truy xuất từ bộ đệm đó.