views:

312

answers:

2

Hello.

When I build and analyze my project on XCode, I obtain a 'warning' on the following line:

NSString *contactEmail = (NSString *)ABMultiValueCopyValueAtIndex(emailInfo, 0);

The message is: Potential leak on object allocated on line ... and stored into contactEmail.

Is there any error on that line?

UPDATE

I get the same 'warning' with this line of code:

ABMultiValueRef emailInfo = ABRecordCopyValue(person, kABPersonEmailProperty);

But here, I can't do this:

[emailInfo release];

I'm developing for iPhone.

+4  A: 

ABMultiValueCopyValueAtIndex is a "Copy" function, which follows the "Create Rule". You need to call CFRelease to release it after finish using it.

NSString *contactEmail = (NSString *)ABMultiValueCopyValueAtIndex(emailInfo, 0);
...
if (contactEmail != nil)
  CFRelease((CFTypeRef) contactEmail);
KennyTM
Since the object is being used as an NSString, it's much more natural to send a release or autorelease message to it than to check for nil, cast it back again and call CFRelease()
Jason Coco
The object *is* an `NSString`.
Williham Totland
@Williham: (1) `ABMultiValueCopyValueAtIndex` returns CoreFoundation objects, which may be a CFString, or other stuff e.g. CFNumber. In fact OP should check before assuming the result is a string, but that's rare case. (2) A CFString can be toll-free-bridged to use NSString methods. A CFString is part of the class-cluster of NSString, but the class is actually NSCFString. @Jason: I prefer to use CF API for CF stuff, but yeah your suggestion also works.
KennyTM
I've updated my question. I also have the same problem with **ABMultiValueRef emailInfo = ABRecordCopyValue(person, kABPersonEmailProperty);**
VansFannel
@KennyTM: (1) Obviously, "The object *is* an `NSString`, assuming it is a `CFString`.". Given a name like `emailInfo`, this seems somewhat likely. (2) An `NSCFString` is also an `NSString`; and saying that CFString *can* be toll-free-briged makes it seem optional. It *is* bridged.
Williham Totland
@Vans: `CFRelease(emailInfo);`
KennyTM
@KennyTM: I prefer that too, but the OP is obviously preferring to use the Foundation classes, so it is more natural to treat the object as a Foundation class, that's all I was saying.
Jason Coco
+1  A: 
  1. The cast is somewhat pointless.
  2. The line might leak, unless you release or autorelease it somewhere.

Edit: For brevity:

NSString *contactEmail = [(NSString *)ABMultiValueCopyValueAtIndex(emailInfo, 0) autorelease];

(The cast might still be pointless, I'm unsure as to how the compiler would handle trying sending a message directly to a CFTypeRef.)

Williham Totland
I've updated my question. I also have the same problem with **ABMultiValueRef emailInfo = ABRecordCopyValue(person, kABPersonEmailProperty);**
VansFannel