У меня есть приложение, которое при первом открытии показывает всех ваших друзей и их изображения профилей и загружает UITableView
с именами ваших друзей, именами пользователей и изображениями профиля в каждой ячейке. Проблема в том, что UITableView
дольше загружает всех друзей, если у вас их много, около 30 например (занимает примерно 5-8 секунд). Я храню все эти изображения в словаре, связанном с именем пользователя друга, поэтому я могу повторно использовать их позже, но основная проблема заключается в том, сколько времени требуется для загрузки всех изображений при первом запуске приложения. Это код, который у меня есть на данный момент, который делает это, перебирая каждого друга:
[auth.loggedInUser getFriendsSuccessCallback:^(NSArray* friends){
for (User* friend in friends) {
if (![weakSelf.friendImageDictionary.allKeys containsObject:friend.userName])
{
UIImage *profilePicture;
if (!friend.profilePicture) {
profilePicture = [UIImage imageNamed:@"ProfilePic"];
}
else
{
NSURL *profilePictureURL = [NSURL URLWithString:friend.profilePicture];
NSData * profilePictureData = [NSData dataWithContentsOfURL:profilePictureURL];
profilePicture = [UIImage imageWithData:profilePictureData];
}
if (profilePicture == nil)
{
profilePicture = [UIImage imageNamed:@"ProfilePic"];
}
[weakSelf.friendImageDictionary setObject:profilePicture forKey:friend.userName];
}
}
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.tableView reloadData];
});
}
Любые советы о том, как значительно сократить время, необходимое для загрузки всех этих изображений?
ПРОГРЕСС:
Итак, я использую AFNetworking
со следующим кодом:
[auth.loggedInUser getFriendsSuccessCallback:^(NSArray* friends){
NSMutableArray *profilePictureRequests = [[NSMutableArray alloc] init];
for (User* friend in friends) {
if (![weakSelf.friendImageDictionary.allKeys containsObject:friend.userName])
{
if (!friend.profilePicture) {
UIImage *profilePicture = [UIImage imageNamed:@"ProfilePic"];
[weakSelf.friendImageDictionary setObject:profilePicture forKey:friend.userName];
}
else
{
NSURL *profilePictureURL = [NSURL URLWithString:friend.profilePicture];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:profilePictureURL];
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
requestOperation.responseSerializer = [AFImageResponseSerializer serializer];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, UIImage* profilePicture) {
NSLog(@"Response: %@", profilePicture);
if (profilePicture == nil)
{
profilePicture = [UIImage imageNamed:@"ProfilePic"];
}
[weakSelf.friendImageDictionary setObject:profilePicture forKey:friend.userName];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Image error: %@", error);
}];
[profilePictureRequests addObject:requestOperation];
}
}
}
for (AFHTTPRequestOperation *requestOperation in profilePictureRequests)
{
[requestOperation start];
}
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.tableView reloadData];
weakSelf.dashboardViewController.loadingCoverView.hidden = YES;
[weakSelf.dashboardViewController.tableActivityIndicator stopAnimating];
NSLog(@"FINISHED LOADING ALL PROFILE PICTURES");
});
}
По сути, я сохранял AFHTTPRequestOperation
в NSMutableArray
для каждого изображения, которое нужно было загрузить. После этого я перебрал NSMutableArray
и начал каждый AFHTTPRequestOperation
.
ВОПРОСЫ:
Это просто сделало загрузку всех изображений ЧРЕЗВЫЧАЙНО быстрой, но я думаю, что делаю это неправильно. Мое представление загрузки с индикатором активности завершается и исчезает ДО того, как все изображения будут загружены и добавлены в мой NSMutableDictionary
, когда это должно происходить ПОСЛЕ того, как все они будут загружены и добавлены. Есть ли способ сделать так, чтобы окно загрузки и индикатор активности исчезли ПОСЛЕ завершения всех UIImage
фоновых потоков загрузки?
ДОПОЛНИТЕЛЬНЫЙ ВОПРОС О AFNetworking
:
Является ли то, как я это делаю (в этом случае одновременно выполняется около 30 фоновых потоков загрузки изображений), не является хорошей практикой с AFNetworking
? Приведет ли это к будущим проблемам, если, скажем, у пользователя более 100 друзей и одновременно происходит более 100 фоновых потоков загрузки изображений?
NSLog("isMainThread = %d", [NSThread isMainThread]);
18.10.2015AFNetworking
, что помогло, но у меня все еще возникают проблемы, которые я включил, когда обновил свой вопрос с моим прогрессом. Не могли бы вы проверить это? 19.10.2015