Threading issues have different effects on ios 7

I am using this project from github, it is an image picker. I had to make a very small change, since ios7, to make preview images from your albums again, but with this change now, when you leave the collector and return to it, the selected photos (2/5) are reset to 0/5, although I have photos. How can i fix this?

It seems that dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0) needs to update ui permanently even with dispatch_async(dispatch_get_main_queue() to reload ui inside it. When I comment on dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0) , I get other things to do with dispatch_async(dispatch_get_main_queue() break that depend on the queue.

here is a code snippet with dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0) I changed the code with the changed code

AGIPCAssetsController.m:

 - (void)loadAssets { [self.assets removeAllObjects]; __ag_weak AGIPCAssetsController *weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ __strong AGIPCAssetsController *strongSelf = weakSelf; @autoreleasepool { [strongSelf.assetsGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { if (result == nil) { return; } AGIPCGridItem *gridItem = [[AGIPCGridItem alloc] initWithImagePickerController:strongSelf.imagePickerController asset:result andDelegate:strongSelf]; if ( strongSelf.imagePickerController.selection != nil && [strongSelf.imagePickerController.selection containsObject:result]) { gridItem.selected = YES; } [strongSelf.assets addObject:gridItem]; }]; } dispatch_async(dispatch_get_main_queue(), ^{ [strongSelf reloadData]; }); }); [strongSelf reloadData]; } 
+8
ios iphone
source share
4 answers

I spent a lot of time on this code, and I could not find the right solution. Apparently, the problem arose on github, and the user suggested a fix:

https://github.com/arturgrigor/AGImagePickerController/issues/19

But apparently, he just deleted all the blocks working in the background, so I believe that for a large number of images the performance will be poor.

My guess is that inside the dispatch_async block, code is executed that calls some UIKit function, and therefore the behavior is mostly undefined.

For example, it seems to me that the setAsset function in AGIPGridItem.m is called inside the dispatch_async you sent. It calls UImage, and although it is inside a lock, it should still execute in the background thread, while all UIKit code should execute on the main one.

UITableViewCell loadable images and reusable cells

But even if I end the call inside dispatch_async(dispatch_get_main_queue()...) , it still doesn't work.

It seems like calling [view removeFromSuperview]; in setItems in AGIPGridell.m somehow responds, but deleting it has a side effect of creating a memory leak (unsurprisingly).

0
source share

AGIPCGridItem is a subclass of UIView . Do not work with UIKit objects in the background thread.

Make sure you need a background thread, and if you do, put only heavy tasks in the background. Creating a UIView should not be in this case.

In addition, it is not recommended to use PRIORITY_LOW use a simple PRIORITY_DEFAULT .

Edit: If you're wondering why this works on iOS 6: this is the UIKit implementation detail. It was still wrong, but somehow did what you expected.

+6
source share

The global dispatch queue is a shared resource. DISPATCH_QUEUE_PRIORITY_LOW tasks are launched after each other task in the queue with a higher priority. If the queue receives many blocks submitted with a higher priority, your DISPATCH_QUEUE_PRIORITY_LOW task may not work for a very long time!

This is described in the Concurreny Programming Guide , as well as the libdispatch manual page.

So, basically, other tasks with a higher priority save the load, and your task with a low priority does not provide an opportunity.

0
source share

I highlighted iMartin's answer: "AGIPCGridItem is a subclass of UIView. Do not work with UIKit objects in the background thread." He got it.

I had a very similar problem when moving iOS6 to 7. I sent an ALAssets request in the background thread. After completing the selection, I will create a UIImageView, UILabel and wrapper, and then send this object to the main / foreground stream that will be displayed. This worked fine on iOS6, but on 7 it wasn't a draw for about 20 seconds. It will someday draw after a user interface event, like a touch.

Fixed to get ALAsset in the background, send it to the main thread, where I created the image, etc. Now works like a charm.

0
source share

All Articles