Skip navigation.
 
mlRE: Threading - How its done?
FROM : Karl von Moller
DATE : Tue May 06 04:17:24 2008

Hi to all,

I have been working on a simple application that lists all available 
PDF's in the Users Documents Folder. I want to fill a Table view with 
only PDF's that exist at that location. When the User selects one of 
the PDF files (by highlighting it in the Table View) it is 
automatically loaded into a PDF View. To make the user interface 
appear more responsive and to let the User know what's going on when a 
large PDF file is loaded, I thought that using Threads would be my 
best answer. I have no experience using threads and like most people 
out in the wild, have no clear starting place to begin learning. The 
easy answer perhaps is to commit to building for 10.5 and use 
NSOperation instead, but I need to be able to build for 10.4 as well!

So I have started down the path of NSThread using this to spawn a new 
thread from my main Thread:

  [NSThread detachNewThreadSelector:@selector(myMethod:) toTarget:self 
withObject:nil];

I have Garbage collection turned ON in my project settings but have 
opted to code an Autorelease Pool in myMethod just incase! Here is a 
portion of my code:

- (void)awakeFromNib
{
   //****** countProcessors will log the number of available CPU cores 
available.
   int countProcessors = MPProcessorsScheduled();
   NSLog(@"the Number of processors on this system are: %d", 
countProcessors);
   
   // **** Init the Mutable arrays which will hold the path and file 
name values
   resultArray = [[NSMutableArray alloc] init];
   fileNameArray = [[NSMutableArray alloc] init];
   [tableViewOutlet setDelegate:self];
   [tableViewOutlet setDataSource:self];
   [windowOutlet setTitle:@"PDF Viewer 1.02 beta"];

   [resultArray removeAllObjects];
   [fileNameArray removeAllObjects];
   NSString *myFileName;
   NSString *thePath = @"~/Documents/";
   NSString *absolutePath = [thePath stringByExpandingTildeInPath];
   
   //** here we setup the default path and open it - read the contents. 
If they are PDF's then add them to the array fileNameArray
   //resultArray stores just the name of the PDF with out reference to 
the rest of the path.
   //I have logged the start and end times as well to see whether 
Threading makes a big difference and it does!
   
   CFAbsoluteTime elapsedTime, startTime = CFAbsoluteTimeGetCurrent();
   
   NSFileManager *myFileManager = [NSFileManager defaultManager];
   NSDirectoryEnumerator *enumerator = [myFileManager 
enumeratorAtPath:absolutePath];
   while (nil != (myFileName = [enumerator nextObject]))
   {
       /* don’t enumerate sub directories */
       [enumerator skipDescendents];
       
       if ([[myFileName pathExtension] isEqualToString:@"pdf"])
       {
           [resultArray addObject: [myFileName lastPathComponent]];
           [fileNameArray addObject: myFileName];
           [tableViewOutlet reloadData];
       }
       else
       {
           NSFont *smallBoldFont = [NSFont fontWithName:@"Arial Black" size:9];
           [currentFileOutlet setFont: smallBoldFont];
           [currentPathOutletLabel setFont: smallBoldFont];
           [pathTextOutlet setStringValue: absolutePath];
           NSFont *myFont = [NSFont fontWithName:@"Arial Black" size:36];
           [numberOfFileOutlet setFont:myFont];
           [numberOfFileOutlet setIntValue:[resultArray count]];
           
       }
   }
   
   elapsedTime = CFAbsoluteTimeGetCurrent() - startTime;
   NSLog(@"list took %f seconds to create. ", elapsedTime);
   
   //******* setup all the text objects with path values etc.
   
   NSString *theFirstIndex = [fileNameArray objectAtIndex:0];
   NSString *interFinal = [absolutePath stringByAppendingString: @"/"];
   finalStringOutput = [interFinal stringByAppendingString: 
theFirstIndex];
   [pdfNameTextLabel setStringValue:[theFirstIndex lastPathComponent]];
   [currentPathOutlet setStringValue: finalStringOutput];
   [fileNameTextOutlet setStringValue: [finalStringOutput 
lastPathComponent]];
   
   //*** go to the method openPDFandCreatePreview to open and create an 
image preview of the selected PDF. Tried this using threads??
   NSLock *myLock = [[NSLock alloc] init];
   [myLock lock];
   [NSThread detachNewThreadSelector:@selector(openPDFandCreatePreview:) 
toTarget:self withObject:nil];
   //[self openPDFandCreatePreview:nil]; // this was used without threads
   [myLock unlock];
   
}

Here is the Method that gets called to produce the image preview of 
the PDF and to load the PDF into the view. Ideally I would like to 
have a progress indicator working as well to give Users some feedback. 
The Application is noticeably faster and more responsive with Threads 
but will crash after a short while! Why? Every error message reported 
after the crash is different so I have no idea what's really going on.

The user interface consists of a spinning progress indicator, a Table 
View with 3 columns (icon, File Name and Path), a Text field where the 
User can enter a specified Path and two buttons. There are several 
text objects to display the chosen file name and path details as well. 
I use Notifications to track changes in selection in the Table View. 
This Method also calls [NSThread 
detachNewThreadSelector:@selector(openPDFandCreatePreview:) 
toTarget:self withObject:nil];

-(void)openPDFandCreatePreview:(id)sender
{
   //[progressOutlet setUsesThreadedAnimation:YES];
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
   [progressOutlet startAnimation:nil];
   NSPDFImageRep  *pdfRep;
   NSImage      *pdfImage;
   pdfRep = [NSPDFImageRep imageRepWithContentsOfFile: finalStringOutput];
   pdfImage = [[[NSImage alloc] init] autorelease];
   [pdfImage addRepresentation: pdfRep];
   [imageWellOutlet setImage:pdfImage];
   PDFDocument    *pdfDoc;
   
   pdfDoc = [[[PDFDocument alloc] initWithURL: [NSURL fileURLWithPath: 
finalStringOutput]] autorelease];
   [pdfOutlet setDocument:pdfDoc];
   [progressOutlet stopAnimation:nil];
   [pool release];
   return;
}


If there is another way to load a PDF into a PDF view using 
Multithreading techniques that is easier to understand please let me 
know! Any help with this would be much appreciated._______________________________________________

Cocoa-dev mailing list (<email_removed>)

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/<email_removed>

This email sent to <email_removed>

Related mailsAuthorDate
mlRE: Threading - How its done? Karl von Moller May 6, 04:17
mlRe: Threading - How its done? John Calhoun May 6, 04:35
mlRe: Threading - How its done? Michael Vannorsdel May 6, 06:28
mlRe: Threading - How its done? Karl von Moller May 6, 06:46
mlRe: Threading - How its done? Michael Vannorsdel May 6, 07:12
mlRe: Threading - How its done? Karl von Moller May 6, 08:07
mlRe: Threading - How its done? Michael Vannorsdel May 6, 12:19
mlRe: Threading - How its done? Karl von Moller May 6, 13:04
mlRe: Threading - How its done? Michael Vannorsdel May 6, 13:10
mlRe: Threading - How its done? Karl von Moller May 6, 13:19
mlRe: Threading - How its done? Michael Vannorsdel May 6, 14:00
mlRe: Threading - How its done? Karl von Moller May 6, 15:25
mlRe: Threading - How its done? Michael Vannorsdel May 6, 16:52
mlRe: Threading - How its done? Michael Ash May 6, 18:34
mlRe: Threading - How its done? Chris Hanson May 8, 07:26
mlRe: Threading - How its done? Michael Vannorsdel May 8, 08:20
mlRe: Threading - How its done? Chris Hanson May 8, 08:45
mlRe: Threading - How its done? Michael Vannorsdel May 8, 09:16
mlRe: Threading - How its done? Scott Ribe May 8, 17:33
mlRe: Threading - How its done? Michael Vannorsdel May 9, 04:49
mlRe: Threading - How its done? Timothy Reaves May 9, 17:49