Reading through Memory Management Policy, I now understand your comment about the difference between the two NSData creation methods. Using dataWithBytesNoCopy:length returns an autoreleased NSData pointer, which is fine if I am going to need an @autorelease block anyway.
Post
Replies
Boosts
Views
Activity
Thanks a lot for the help and additional pointers. I do have a few additional questions though.
To get straight to the point, I believe the following code fixes the issue I was seeing:
void Write(CBPeripheral *p, CBCharacteristic *c, void *bytes, int len) {
@autoreleasepool {
NSData *data = [[NSData alloc] initWithBytesNoCopy:bytes length:len];
[p writeValue:data forCharacteristic:c type:CBCharacteristicWriteWithoutResponse];
[data release];
}
}
I changed the way the NSData is allocated so that the alloc..release pattern is more clear. I still don't understand if that was actually an issue though - my mental model was that [NSData dataWithBytesNoCopy:bytes length:len] would be functionally equivalent to the explicit alloc/init way, so am I still missing something there ?
The other issue, which I added the @autoreleasepool block for, was that the CBPeripheral writeValue:forCharacteristic:type: method was retaining a reference to data, and then autoreleasing it (if I reduced the scope of my autorelease block to just around that API call, I could see the retainCound drop after exiting the block). That is surprising to me given that the documentation mentions that API copies the data so one wouldn't expect it to be retained. In my particular use case, I think it lead to the data being leaked because my application (again, the main code is in go language) does not have a cocoa main event loop that would be responsible for draining the (implicit) autorelease pool.
I wonder if there are any other gotchas that I would need to know about for interfacing with objective-C APIs when my main application is not written with a cocoa framework ? So far the other one I've hit is that I needed to explicitly create a dispatch queue for my delegate objects or they wouldn't receive any messages.