Why does the Xcode 4.5 static analyzer tell me that I have a potential memory leak when I try to use __attribute__((NSObject)) - objective-c

I have a property that holds a Core Foundation object, specifically a CFHTTPMessageRef. I've tried using the attribute((NSObject)) macro to tell the compiler to treat the referenced object as a normal NSObject and handle the retaining and releasing of that object for me rather than having to CFRelease myself. I've tried changing the property to weak instead of strong, but nothing seems to work, the static analyzer still tells me I have a memory leak, and from the looks of the output from CFGetRetainCount, it would that it's right. Does anyone know why my property would cause a memory leak:
typedef __attribute__((NSObject)) CFHTTPMessageRef HTTPMessageRef;
#interface ABRemoteConnection : NSObject
#property (strong) HTTPMessageRef message;
#end
- (void)dataReceived:(NSNotification *)notification {
self.message = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE);
// do some stuff and if the message is complete, use it and release the
// message object
if (messageIsComplete(self.message)) {
self.message = NULL;
}
}

From the documentation, it looks like __attribute__((NSObject)) is only meant to be used with retain.
But switching strong to retain means you're now adding another ref which the prop is going to manage for you; there's still the original ref that you have to CFRelease.
If you think about it, this makes sense. Imagine doing the same thing with a property(retain) NSObject *:
- (void)dataReceived:(NSNotification *)notification {
self.o = [[NSObject alloc] init];
}
This works fine—but only because ARC sees the alloc and automatically inserts a corresponding release for you at the end of the scope. With a CF___Create function, there's no automatic CFRelease at the end of the scope, so you have to manually write one.
If you really want HTTPMessageRef to be as convenient as, say, NSDictionary, it can't just be a typedef; it has to be a toll-free bridged class.

Related

Circular references in Objective-C and clang

Why doesn't the static analyser detect circular references with blocks? I remember it used to do it when I had retains on my delegates instead of assign, pre-blocks introduction. I remember the nice little lines it used to draw on my code (i think...)
If I do this, without using weakSelf, I know I'm going to get a circular reference.
// Note 1: myObject is 'retained' by self.
// Note 2: myObject retains the block for the future
[self.myObject registerBlockOfCodeForFutureExectution:^{
[self doSomething];
}];
Sample Project Exploiting Issue
Now if I know this, and I'm a stupid human, then why doesn't my intelligent computer know this is bad and warn me that I'm being stupid?
There must be a logical reason why it can't detect it, and I want to know what that reason is.
This question is regarding clang and static analysis, please don't suggest how I fix circular references - I know how to do this.
If you use self inside of block it does not automatically mean that you get retain cycle. You get retain cycle only if life-time of block depends on life-time of self object. That may be the case if self has strong reference to myObject or some more complex dependencies are also possible (I assume that it indeed 'saves' block passed to a method, so you already have strong reference there).
So to have retain cycle in your example you need to have two following conditions met (neither of them follows from the code you posted), and compiler needs to be aware of them:
1. Life-time of myObject is tied to self - lets assume that self has strong reference to it
2. saveThisBlockInMyObject: retains block passed to it
I made a small sample that gives compiler warning about capturing self - to address 1st point I declared myObject as a strong property of some class:
#property (strong) MyTestClass* myObj;
...
self.myObj = [MyTestClass new];
For 2nd point I could not find a way to specify that method retains its argument (there're source annotations for returned values, but there's no relevant annotations for method parameters). But you declare block as a strong property of your test class, then compiler is happy to warn you about possible retain cycle:
typedef void (^MyVoidBlock)();
// MyTestClass
#property (nonatomic, copy) MyVoidBlock voidBlock;
self.voidBlock = ^{
[self doSomething]; // Warning!
};
Hope that makes sense :)
The code posted to github does cause a retain cycle.
Current github code:
#interface MyObject ()
#property (nonatomic, copy) dispatch_block_t codeToRunInFuture;
#end
#implementation MyObject
- (void) registerBlockForFuture:(dispatch_block_t)block {
self.codeToRunInFuture = block;
}
// Call in ViewController
self.myObject = [MyObject.alloc init];
[self.myObject registerBlockForFuture:^{
[self runThisInFuture];
}];
I can see where this would be difficult to catch since the Analyzer can not know what block might be and therefore can not tell if there is a self reference either strong or weak. It would have to examine all instances where registerBlockForFuture: is called and the block in each case.
The answer might be to submit a bugreport to Apple.

Objective C: Differentiating iVars and Accessors

#interface RandomObject : NSObject
{
NSString* someObject; // I know I don't have to explicitly declare. Just to clarify my point.
}
#property (nonatomic, strong) NSString *someObject;
#end
#implementation RandomObject
#synthesize someObject;
#end
Given the code above and Xcode 4.3 is used (hence, no auto-synthesizing), here is my question.
The property/synthesize will create accessors for someObject, namely getter and setter. So if I want to assign a value to someObject, I can do this.
self.someObject = #"Tomato"; // [self setSomeObject: #"Tomato"];
If my understanding is correct, self will send #"Tomato" to setSomeObject method. But what if you do this?
someObject = #"Tomato"; // or maybe _someObject = #"Tomato" if you are doing auto-synthesizing
Directly accessing an iVar object seems like a bad idea, but since someObject is a private variable, within the same class you have access to that, right?
I understand why you would need to use self.someOject if you want to manipulate someObject from another class. But why is it that you'd need to do the same even though you are still in the same class. Why is it that it's a bad idea to directly access iVar.
Generally speaking accessors have more pros than cons and I use them everywhere I can.
The main issue is that every place you reference the ivar directly is another potential place your code will need to change.
For example imagine you have referenced someObject in multiple places throughout your class. Then the requirements change and now you decide that when the value of someObject is assigned you need to so some other work. Due to the fact that you have accessed the ivar directly throughout the class you now have to either duplicate this new code everywhere you assign someObject or refactor. If you was using an accessor you just have one piece of code to change
- (void)setSomeObject:(id)anObject
{
if (anObject != someObject) {
someObject = anObject;
[self doSomeWork];
}
}
You can have the same issue with the getter - imagine you store an array of objects in someObjects - this works great but then later down the line you decide that you don't actually need to store someObjects as it can be dynamically computed from other values. If you have directly accessed the ivar everywhere then this becomes a big chore. If you stick to abstracting someObject behind a getter then all you now have to do is
- (NSArray *)someObjects
{
return [self calculateSomeObjects];
}
This is exactly the idea with non-ARC code, which puts the memory management of the ivar in one place (behind accessors) so that you do not have to litter your code with repetitive code.
The property does more than just assigning an object to the ivar.
If you don't use ARC, the property will auto-generate retain/release code to handle memory management. Just calling someObject = #"Tomato" creates a memory leak (if someObject is assigned)
If your property is atomic, the property will provide thread safety, while accessing the ivar would not be thread safe.
See https://stackoverflow.com/a/589348/1597531 for examples of auto-generated property code.

How do I release properties that are added at runtime in a category?

Given the following category definition how might I handle -dealloc both with and without ARC? I am currently using ARC and to the best of my knowledge and poking around in Instruments, the properties are being cleaned up but I am not 100% confident in that.
#interface NSObject (SuperUsefulThingIWishAllNSObjectsHad)
#property (nonatomic, copy) NSString *foo;
#end
#import <objc/runtime.h>
#implementation NSObject (SuperUsefulThingIWishAllNSObjectsHad)
static const void *MyPropertyKey = &MyPropertyKey;
#dynamic foo;
- (NSString *)foo
{
return objc_getAssociatedObject(self,
MyPropertyKey);
}
- (void)setFoo:(NSString *)foo
{
objc_setAssociatedObject(self,
MyPropertyKey,
foo,
OBJC_ASSOCIATION_COPY);
}
This is more for my own edification but if the solution isn't too hacky I may have some places I actually want to use this.
You don't need to do anything special in dealloc to “clean up” an associated object. The runtime takes care of it for you. This is independent of ARC.
If you're not using ARC, you need to be sure to call [super dealloc] in your own dealloc overrides. But you need to do that regardless of your use of associated objects, and the compiler will warn you if you forget.
UPDATE
In response to your comment: You're right that the Objective-C Runtime Reference doesn't explicitly say the associated object is released (if appropriate based on the association policy) when the main object is deallocated. But that is the only reasonable action, because the point of an associated object is to attach a subordinate object to a main object without changing the main object's source code.
Anyway, the source code of the Objective-C runtime is open source, so we can inspect it to verify that this is indeed what's implemented.
Look at NSObject.mm and you'll see that -[NSObject dealloc] calls _objc_rootDealloc, which calls object_dispose.
The object_dispose function is in objc-runtime-new.mm, and it calls objc_destructInstance, which calls _object_remove_assocations.
The _object_remove_assocations function (yes, it has a typo in the source code) is in objc-references.mm. It removes all objects associated with the object being deallocated, releasing them if appropriate. If you look at objc_removeAssociatedReferences, which is part of the public API and is defined in objc-runtime.m, you 'll see that it also calls _object_remove_assocations.

Should I use #property (retain) for a #dynamic property setter that is retaining?

I have the following code for a property whose getter/setter I write manually using the #dynamic keyword:
#property (nonatomic, retain) NSObject* obj;
#dynamic obj;
-(NSObject*) obj
{
return obj;
}
-(void) setObj:(NSObject*)newObj
{
[obj release];
obj = [newObj retain];
}
My question is, if I remove the retain from the #property declaration, the compiler complains that the default will be assign and that it may not be what I want. If I add the retain, I assume it is going to be ignored, because I wrote the getters/setters myself?
Just looking for a quick confirmation on this.
You are correct, but your property declaration is as much for documentation as it is for your implementation, at least in this case. At some point, someone (you in six months?) will look at your .h file and say, "Why isn't this value being retained? How does this not crash every time it gets run or leak memory like a sieve?"
The retain allows your object to stay allocated in memory until you apply
[obj release];
so even if you do have your own setter and getter you need to keep the retain to keep your place in memory, because in the end you only have a pointer to that position and that is why the compiler tels you that you may modifying another object or what ever takes the place of your object.
And its important that you make the release to free the memory when you are done using it.

Objective-C 2.0; Assigning a Property; Leaking Memory?

I'm still learning about Objective-C memory management. I'm trying to implement several simple classes in an example program that I'm building.
As an example, say I have the following class definition:
#import <UIKit/UIKit.h>
#interface customViewController : UIViewController
{
customObject *myCustomObject;
}
#property (retain) customObject *myCustomObject;
- (void)replaceCustomObject:(customObject *)newObject;
#end
For the property, I use the standard synthesize keyword...
#synthesize myCustomObject;
Then please assume that in the instance of customViewController the myCustomObject is already set with a valid value and is in use. Then the method replaceCustomObject is defined as:
- (void)replaceCustomObject:(customObject *)newObject
{
//Does this cause a memory leak because I just assign over
//the existing property?
self.myCustomObject = newObject;
}
As the comment asks, does this leak memory? Or is this the valid way to replace a previous object with a new object?
Thank you,
Frank
As others have mentioned, your code is perfectly valid and won't leak memory when assigning to the property.
If you have forgotten to implement a proper dealloc method, the last object assigned will be leaked when your customViewController is destroyed. A proper dealloc implementation would look like so:
- (void)dealloc
{
self.myCustomObject = nil;
[super dealloc];
}
That's perfectly valid, and does not leak memory. The synthesized accessors manage retain counts correctly.
(As an aside, you don't need that replaceCustomObject: method; since your property is readwrite by default, you have an auto-generated setCustomObject: method that clients of your class can use, and which follows the normal Cocoa naming conventions.)
According to this, if you use (retain) in your declaration, the synthesized method will release the old value first, then retain the new one:
if (property != newValue) {
[property release];
property = [newValue retain];
}
the property accessor syntax
self.x = y;
has the same effect as calling the setter method explicitly:
[self setX:y];
The accessor method will do whatever it has been written to do. In your case, for a #property(retain) property that has been #synthesized, the accessor will release the old object and retain the new one.
So, calling the setter, whether explicitly or through the '.' syntax, will do the right thing - including the right memory management.
So in short: no, this will not leak memory.