Neo
Neo

Reputation: 4880

Objective-C: Potential leak of an object stored into NSDictionary

I am a newbie to Objective-C. XCode highlights the following code as an issue. _myCookies is a private variable of my class where I store the received cookies.

@implementation MessageSender {
  NSArray *_myCookies;
}
...
// Socket open callback
- (void) gotData:(MySocket *) socket {
  NSDictionary *responseHeaders = (__bridge NSDictionary*)CFHTTPMessageCopyAllHeaderFields(socket.HTTPHeaders);
  _myCookies = [NSHTTPCookie cookiesWithResponseHeaderFields:responseHeaders
                                                         forURL:[NSURL URLWithString:@""]];

}

enter image description here

The highlighted issues are:

  1. Call to function 'CFHTTPMessageCopyAllHeaderFields' returns a Core Foundation object with a +1 retain count
  2. Object leaked: object allocated and stored into 'responseHeaders' is not referenced later in this execution path and has a retain count of +1

How do I resolve this one? I am using ARC. I want to store the cookies in my class so I can later use them while sending the request, but I want to let the socket take care of its responseHeaders.

Upvotes: 1

Views: 1447

Answers (2)

Greg
Greg

Reputation: 9168

You need to transfer ownership of the CoreFoundation object to ARC:

NSDictionary *responseHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(socket.HTTPHeaders));

CF objects are not managed by ARC, and must be released manually. When you use a __bridge cast, you're simply casting the object directly with no change in ownership. This is what causes your memory leak (you need to manually release CF objects with CFRelease when you're done with them).

You can avoid all this manual memory management trouble by simply using CFBridgingRelease to cast the object (as in the code example above). This transfers ownership of the CF object to ARC, so ARC will automatically handle releasing that object for you, and everything will work just fine with no extra work on your part.

Upvotes: 5

Aaron Wojnowski
Aaron Wojnowski

Reputation: 6480

Instead of __bridge, use __bridge_transfer which transfers ownership of the object to ARC. Ex:

NSDictionary *responseHeaders = (__bridge_transfer NSDictionary*)CFHTTPMessageCopyAllHeaderFields(socket.HTTPHeaders);

Upvotes: 2

Related Questions