On Jun 20, 2011, at 8:43 PM, James Merkel wrote:



On Jun 20, 2011, at 7:23 PM, Conrad Shultz wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 6/20/11 3:54 PM, James Merkel wrote:
I'm opening all  digital camera files in a folder (JPEG, TIF, etc),
extracting a thumbnail and some Exif data, and putting the data in a
TableView. The time consuming part is finding the thumbnails in the files.

OK.

I don't know anything about extracting thumbnails et al., but for the
sake of argument suppose you have a class JMImageProcessor that has
methods like:

- - (id)initWithFileHandle:(NSFileHandle *)fileHandle;
- - (NSDictionary *)exifData;
- - (NSImage *)thumbnail; // Takes a long time to run

So in your main thread you then have a loop over a bunch of
NSFileHandles (of course you might be accessing the files completely
differently; this is just for illustration). So you might currently have:

for (NSFileHandle *fileHandle in files) {
        JMImageProcessor *processor = [[JMImageProcessor alloc]
initWithFileHandle:fileHandle];
        // Call some code to stash the results, presumably updating the
tableView's data source in the process
        [self setExifData:[processor exifData] forFile:fileHandle];
        [self setThumbnail:[processor thumbnail] forFile:fileHandle];
        [processor release];
        // Call some code to redisplay the NSTableView
        [self updateTable];
}




You could make such code non-blocking with, for example, GCD:




dispatch_queue_t workerQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL);

for (NSFileHandle *fileHandle in files) {
        dispatch_async(workerQueue,
                ^{
                        JMImageProcessor *processor = [[JMImageProcessor alloc]
initWithFileHandle:fileHandle];
                        [self setExifData:[processor exifData] 
forFile:fileHandle];
                        [self setThumbnail:[processor thumbnail] 
forFile:fileHandle];
                        [processor release];
                        dispatch_async(dispatch_get_main_queue(),
                                ^{
                                        [self updateTable];
                                        // UI updates need to be on the main 
thread, i.e., the GCD main
queue, so we call back asynchronously
                                }
                        );
                }
        );
}

(Note 1: this was all written in a mail client and untested.)

(Note 2: the above assumes that the setExifData/setThumbnail methods are
implemented properly, atomically if required.  But if the methods are
backed by, for example, mutable dictionaries, and anything accessing
them handle absent entries reasonably, this should be pretty
straightforward.)

(Note 3: this could all alternatively be done with NSOperationQueue, or
even plain old NSThread.  But GCD can probably do it in the smallest
amount of code.)

Good luck!

- --
Conrad Shultz

Synthetiq Solutions
www.synthetiqsolutions.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFOAACvaOlrz5+0JdURAvzkAJ9XaQ4CqRXY4k6fKtRdVkqcYBeBewCeL8fh
jOJSgWEisHfOU6/WflFoukA=
=swOg
-----END PGP SIGNATURE-----

First of all (kind of basic) what is GCD ?

I have actually implemented this a couple of different ways (not using threads). At first I just had lazy loading of the TableView. Whenever the TableView needed something a file was accessed and a thumbnail extracted. Then I changed it to do preprocessing. That is, everything was extracted from the files and then the TableView was allowed to load. The first approach uses less memory but is slower in updating the TableView (when it is scrolled for example). The second approach uses more memory but is faster in updating (provides a better user experience). I think trying to do this in a separate thread would be much cleaner using the second approach.

I forgot to mention the really slow case: if a thumbnail can't be found in the file, then I make a thumbnail from the main image. If this has to be done on a lot of files, then things really bog down.

Jim Merkel



Ok, I see GCD == Grand Central Dispatch. Available on Snow Leopard.
I'm on 10.5.8. I'll probably have to buy a new machine and get back to you on this!

Jim Merkel
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to