[ Updating UI (labels) while downloading Images in iOS ]
This is the function to download images , in this function i have to update the UI, the UILabels that shows total images and counter value (downloaded images).
thats why i am calling a thread.
-(void) DownloadImages
{
NSLog(@"Images count to download %lu",(unsigned long)[productID count]);
if ([productID count] > 0)
{
// Document Directory
NSString *myDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
for (i = 0; i < [productID count]; i++)
{
[NSThread detachNewThreadSelector: @selector(UpdateLabels) toTarget:self withObject:nil];
// [self UpdateLabels]; this does not work….
NSLog(@"image no %d", i);
//[self Status];
NSString *imageURL = [NSString stringWithFormat:@"http://serverPath/%@/OnlineSale/images/products/%@img.jpg",clientSite,[productID objectAtIndex:i]];
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
// Reference path
NSString *imagePath = [NSString stringWithFormat:@"%@/%@-1-lrg.jpg",myDirectory,[productID objectAtIndex:i]];
NSData *imageData = [NSData dataWithData:UIImageJPEGRepresentation(image, 1.0f)];
[imageData writeToFile:imagePath atomically:YES];
}
NSLog(@"Downloading images completed...");
}
}
Problem: - here for every new image i have to call every time a new NSThread, there may be thousands of images and it looks bad that there will be thousands threads.
- in simulator i have tested it for 3000 images, but in my iPad when testing it gives the error,,, App is Exited and terminated due to memory pressure.
i guess the error is due to this calling approach of new thread every time.
what i am doing wrong here.?????????????
i have searched there are two different options but i don't know which one is right option,
Options are:
- [self performSelectorInBackground:@selector(UpdateLabels) withObject:nil];
- [NSThread detachNewThreadSelector: @selector(UpdateLabels) toTarget:self withObject:nil];
and i also want to know that if i use
[NSThread cancelPreviousPerformRequestsWithTarget:self];
just after the call of selector, is it right approach or not..???
Answer 1
My suggestion is to use NSOperationQueue . you could then set the maxConcurrentOperationCount property to whatever you like. In addition in your case is the best approach. Make some research on what are your maxConcurrentOperationCount with how many concurrent thread your iphone could run without any issue. NSOperationQueue will manage this for you run new thread with this limitation.
It should look something like this:
NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];
[myQueue setMaxConcurrentOperationCount:500];
for (i = 0; i < [productID count]; i++) {
[myQueue addOperationWithBlock:^{
// you image download here
}];
}
but check apple reference first.