Ausgabe
Ich habe eine objc-Funktion, die zurückkehrtSecIdentityRef
+ (SecIdentityRef)getSecIdentity {
NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"cert1" ofType:@"p12"];
NSData *p12Data = [NSData dataWithContentsOfFile:resourcePath];
NSMutableDictionary * options = [[NSMutableDictionary alloc] init];
[options setObject:@"123456" forKey:(id)kSecImportExportPassphrase];
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = SecPKCS12Import((CFDataRef) p12Data,
(CFDictionaryRef)options, &items);
if (securityError == noErr && CFArrayGetCount(items) > 0) {
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
SecIdentityRef identityApp =
(SecIdentityRef)CFDictionaryGetValue(identityDict,
kSecImportItemIdentity);
CFRelease(items);
return identityApp;
}
CFRelease(items);
return NULL;
}
Ich importiere die Klasse mit dieser Funktion in den Bridging-Header und verwende sie dann in Swift-Code
let test = Certificate.getSecIdentity()
let secIdentity = test.takeUnretainedValue()
Von Certificate.getSecIdentity()
Rückgaben Unmanaged<SecIdentityRef>
mit korrekter (?) SecIdentity im Inneren.
Am test.takeUnretainedValue()
(und test.takeRetainedValue()
) erhalte ich
Thread 1: EXC_BAD_ACCESS (code=1, address=0x2d13e474f3e0)
Was ich falsch mache? Wie erhalte ich SecIdentity?
Lösung
Wenn Sie ein Element aus (glaube ich) einer Kernsammlung abrufen, folgen die Sammlungsfunktionen der Get-Rule . Das bedeutet, dass Sie das Element nicht besitzen, bis Sie es ausdrücklich behalten. Also in diesem Teil Ihres Codes:
SecIdentityRef identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity); CFRelease(items);
Sie geben im Wesentlichen sowohl items
als auch frei identityApp
und geben einen baumelnden Zeiger zurück (um genau zu sein, eine baumelnde Kernfundament-Referenz). Behalten Sie einfach die Instanz von SecIdentityRef
vor Ihrer Veröffentlichung des items
Arrays wie folgt bei:
CFRetain(identityApp);
CFRelease(items);
return identityApp;
PS Da Ihre Funktion möglicherweise zurückgibt NULL
, sollten Sie besser das Ergebnis erstellen nullable
, insbesondere wenn Sie mit Swift arbeiten, damit es weiß, dass das Ergebnis ein optionaler Wert ist:
+ (nullable SecIdentityRef)getSecIdentity
PPS Sie können Ihren Code auch direkt in Swift umschreiben, da es die Arbeit mit unterstütztSecCertificate
Beantwortet von – The Dreams Wind
Antwort geprüft von – Mildred Charles (FixError Admin)