我正在尝试使用MacOS上的Swift制作从打印机ID到打印机名称的地图。
Objective-C版本如下。这很有效。
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
CFArrayRef printerList;
PMServerCreatePrinterList(kPMServerLocal, &printerList);
NSMutableDictionary<NSString*,NSString*> *result = [NSMutableDictionary<NSString*,NSString*> dictionary];
if (printerList) {
CFIndex numberOfPrinters = CFArrayGetCount(printerList);
for (CFIndex printerIndex = 0; printerIndex < numberOfPrinters; printerIndex++) {
PMPrinter printer = (PMPrinter)CFArrayGetValueAtIndex(printerList, printerIndex);
CFStringRef printerID = PMPrinterGetID(printer);
CFStringRef printerName = PMPrinterGetName(printer);
result[(__bridge NSString*)printerID] = (__bridge NSString*)printerName;
}
NSLog(@"Result1 = %@", result.description);
}
CFRelease(printerList);
NSLog(@"Result2 = %@", result.description);
}
return 0;
}
另一方面,以下Swift版本与EXC_BAD_ACCESS崩溃。
import Foundation
var printerList : Unmanaged<CFArray>?
let kPMServerLocal = unsafeBitCast(0, to: PMServer.self) // #define kPMServerLocal ((PMServer)NULL)
PMServerCreatePrinterList(kPMServerLocal, &printerList)
var result : [String : String] = [:]
if let list = printerList {
let retainedList = list.takeRetainedValue()
let numberOfPrinters = CFArrayGetCount(retainedList)
for printerIndex in 0..<numberOfPrinters {
let printer = CFArrayGetValueAtIndex(retainedList, printerIndex)
let printerID = PMPrinterGetID(OpaquePointer(printer)!)!.takeRetainedValue() as String
let printerName = PMPrinterGetName(OpaquePointer(printer)!)!.takeRetainedValue() as String
result[printerID] = printerName
}
print("Result1 = " + result.description) // Successful
}
print("Result2 = " + result.description) // EXC_BAD_ACCESS
我猜内存管理不合适。如何修改代码?