调用PDFDocument writeToFile方法崩溃,请求技术协助
Let's break down the issues in your code that are likely causing the crash, along with step-by-step fixes and additional checks:
1. Critical Type Mismatch in Pattern Color Initialization
The most obvious bug is how you're creating the pattern color:
NSColor *interiorColor = [NSColor colorWithPatternImage:@"TestImage"];
The colorWithPatternImage: method expects an NSImage object, not a string. Passing a string here will trigger an unrecognized selector crash or memory access error immediately. Fix this by first loading your image properly:
// Load image from your project's asset catalog (if added there) NSImage *patternImage = [NSImage imageNamed:@"TestImage"]; // Or load from a specific file path if needed: // NSImage *patternImage = [[NSImage alloc] initWithContentsOfFile:@"/full/path/to/TestImage.png"]; if (patternImage) { NSColor *interiorColor = [NSColor colorWithPatternImage:patternImage]; annotation.interiorColor = interiorColor; } else { NSLog(@"Warning: Could not load pattern image 'TestImage'"); // Fallback to a solid color to avoid further issues annotation.interiorColor = [NSColor lightGrayColor]; }
2. Improper Initialization of PDFAnnotationSquare
Using init for PDFAnnotationSquare isn't recommended—Apple's documentation specifies using the designated initializer to ensure all required properties are set correctly, which prevents crashes from uninitialized values:
// Replace [[PDFAnnotationSquare alloc] init] with this designated initializer: PDFAnnotationSquare *annotation = [[PDFAnnotationSquare alloc] initWithBounds:NSMakeRect(100.0, 100.0, 300, 300) forType:PDFAnnotationSquareWidget withProperties:nil];
This initializes the annotation with its bounds upfront, eliminating potential nil property issues later.
3. Validate PDF Document and Page Existence
Before modifying the PDF, add checks to ensure your document and target page are valid—accessing a nil document or non-existent page will crash your app:
if (!self.pdfDocument || self.pdfDocument.pageCount == 0) { NSLog(@"Error: PDF document is nil or has no pages"); return; } PDFPage *page = [self.pdfDocument pageAtIndex:0]; if (!page) { NSLog(@"Error: Could not retrieve page at index 0"); return; }
4. Use a Writable File Path
Hardcoding @"SomePath" will almost certainly fail because your app doesn't have permission to write to arbitrary locations. Use the user's Documents directory instead:
// Get the user's Documents folder path NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = paths.firstObject; NSString *outputPath = [documentsDirectory stringByAppendingPathComponent:@"annotated.pdf"]; // Write with error handling to catch permission or file issues NSError *writeError = nil; BOOL saveSuccess = [self.pdfDocument writeToFile:outputPath error:&writeError]; if (!saveSuccess) { NSLog(@"Failed to save PDF: %@", writeError.localizedDescription); }
Full Corrected Code
Putting all fixes together, here's the stable version of your code:
// Validate PDF document first if (!self.pdfDocument || self.pdfDocument.pageCount == 0) { NSLog(@"Error: Invalid or empty PDF document"); return; } PDFPage *page = [self.pdfDocument pageAtIndex:0]; if (!page) { NSLog(@"Error: Could not access page 0"); return; } // Initialize annotation correctly PDFAnnotationSquare *annotation = [[PDFAnnotationSquare alloc] initWithBounds:NSMakeRect(100.0, 100.0, 300, 300) forType:PDFAnnotationSquareWidget withProperties:nil]; // Load and set pattern color properly NSImage *patternImage = [NSImage imageNamed:@"TestImage"]; if (patternImage) { annotation.interiorColor = [NSColor colorWithPatternImage:patternImage]; } else { NSLog(@"Warning: Pattern image missing, using fallback color"); annotation.interiorColor = [NSColor lightGrayColor]; } [page addAnnotation:annotation]; // Save to a valid, writable path NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *outputPath = [paths.firstObject stringByAppendingPathComponent:@"annotated.pdf"]; NSError *writeError = nil; if ([self.pdfDocument writeToFile:outputPath error:&writeError]) { NSLog(@"PDF saved successfully to: %@", outputPath); } else { NSLog(@"Save failed: %@", writeError.localizedDescription); }
Additional Troubleshooting Tips
- If crashes persist, enable Zombies Instrument in Xcode to track down deallocated objects being accessed.
- Check the crash log for specific error messages (like
EXC_BAD_ACCESSor unrecognized selectors)—they'll point directly to the problematic line. - Double-check that your "TestImage" asset is added to your project and has the correct target membership in Xcode.
内容的提问来源于stack exchange,提问作者sharmada

