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 (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 [EMAIL PROTECTED]

Reply via email to