Tom Tom - 7 days ago 5
Objective-C Question

Casting a CFErrorRef to an NSError (or opposite) with ARC

I used to cast an NSError to CFErrorRef like this and using it in SMJobBless

NSError *error
BOOL removed = SMJobRemove(kSMDomainSystemLaunchd,
(CFStringRef) daemonBundleID,
auth,
true,
(CFErrorRef*) &error);
if (!removed) {
NSLog(@"Failed to remove existing PacketTool");
[NSApp presentError: error];
}


As I've had errors with ARC, "Cast of an indirect pointer to an Obj-C pointer to 'CFErrorRef' is disallowed with ARC", I changed and decided to do the opposite

CFErrorRef *cfError = nil;
BOOL blessed = SMJobBless(kSMDomainSystemLaunchd, (__bridge CFStringRef)daemonBundleID,
auth,
cfError);
if (!blessed) {
NSError *error = (__bridge NSError *)cfError;
NSLog(@"Failed to bless PacketTool: %@", error);
[NSApp presentError: error];
return FALSE;
}


Now I've got an "Incompatible types casting 'CFErrorRef' to NSError *" with __bridge cast

What can I do?

Update: Thanks to Greg, correct code is now:

CFErrorRef cfError = nil;
BOOL blessed = SMJobBless(kSMDomainSystemLaunchd,
(__bridge CFStringRef) daemonBundleID,
auth,
&cfError);
if (!blessed) {
NSError *error = (__bridge NSError *)cfError;
NSLog(@"Failed to bless PacketTool: %@", error);
[NSApp presentError: error];
return FALSE;
}

Answer

When you declare cfError you shouldn't use pointer *, you should use:

CFErrorRef cfError = nil;
NSError *error = (__bridge NSError *)cfError;

In the other way it works like that:

NSError *error = nil;
CFErrorRef ref = (__bridge CFErrorRef) error;

Hope this help.