Potential Leak of Object stored into a NSMutable dictionary (GPUImageFramework) iOS 8+ - objective-c

I am new to Objective C, and I would really appreciate any help resolving a memory leak. I am trying to resolve memory management issues that occur in the GPUImageFramework.
In the method below I am getting the following messages highlighted in blue:
Method returns an Objective-C object with a +1 retain count
Object leaked: allocated object is not referenced later in this execution path and has a retain count of+1
-(void)setAndExecuteUniformStateCallbackAtIndex:(GLint)uniform forProgram:(GLProgram *)shaderProgram toBlock:(dispatch_block_t)uniformStateBlock;
{
[uniformStateRestorationBlocks setObject:[uniformStateBlock copy] forKey:[NSNumber numberWithInt:uniform]];
uniformStateBlock();
}
enter image description here
I take it that the method being stored in the NSMutable dictionary needs to be released into memory.
Please can somebody point me in the right direction?

I have ARC enabled within the GPUImageFramework
You either need to enable it for your project, not just for the framework, or you need to handle memory management manually.
The sub-expression [uniformStateBlock copy] returns an object with, in the language of the error, "+1 retain count"; i.e. an object the caller "owns" and which the caller must release.
When your code inserts an object into the array the array itself also takes ownership, i.e. does a retain. It does not take ownership from the caller, it is still left owning the block returned by copy and it is this ownership which is never relinquished which results in the leak, as the error states.
If you enable ARC it will take care of this and release the callers ownership of the block at the appropriate point.
Otherwise you can leave ARC off and insert a release call when the caller no longer requires the block (which still leaves the array with ownership).
HTH

Related

How can I check if object isn't deallocated on Objective-C?

How can I check if object isn't deallocated on Objective-C?
The following standard condition checks only if object is initialized:
NSObject *objectVariable = nil;
...
if (objectVariable) {...}
You can't check after-the-fact whether an object is already deallocated or not, because it is invalid to do anything with an object that is deallocated (once an object is deallocated, any pointer that used to point to it is now an invalid pointer, and dereferencing it is undefined behavior). And since you don't know whether it is deallocated or not, and it may be deallocated, you cannot meaningfully examine it in any way. And a deallocated object may well "look like" a valid object if you try to examine it (it is undefined behavior, so any behavior is possible).
If this is an object of your own class, the obvious thing would be to print something or perform some other indicator action in the class's -dealloc method. That will tell you when it is deallocated.
Even if this is an object that is not of your own class, you may be able to either 1) add -dealloc as a category method, if the class doesn't override -dealloc, or 2) swizzle the -dealloc method, if the class does override it. Then you can print something in your version.
You can also profile it in Instruments; the Allocations instrument can tell you how many objects of a given class have been allocated, and how many are alive. If you suspect that you are losing track of objects or there is a retain cycle, the Leaks instrument may be able to tell you that.
I'm in agreement with the comments, If you're doing memory management right, there should be no need for such a check. Nor am I aware of such a check, if the address gets populated with a new object, the check would pass but could still crash your app.
My suggestions are to:
Read up on manual memory management rules, pay special attention to how blocks affect memory management, alloc/init methods, when to use assign, etc. Memory management rules should become second nature to you. Start with this Apple guide.
Run static analysis on your app and fix any memory errors. Fix all the errors really, these are bugs in your app. (CMD+Shift+B or Product->Analyze in the menu)
Reproduce the crash in Instruments using zombies. Read the retain/release report to find out where the object may have been over-released. (CMD+I or Product->Profile. Select Zombies in the window that appears)
Consider converting to ARC. Converting to ARC doesn't get you completely off the hook for understanding ObjC memory management, but it will take a lot of the burden off of you.

Dealloc and ARC

I read that when using ARC in Objective-C programming in Xcode the dealloc method is called automatically by the compiler. Under what circumstances is it called?
In order to avoid having too many variable names, when I need to repeatedly use the same classes to do multiple operations (and resetting the variable each time) I often declare the variables, set them to nil, and then assign values to them as I go. This ends up looking like this:
MyClass mc;
mc = [[MyClass alloc] init];
[mc doThis:someOption]
mc = [[MyClass alloc] init];
[mc doThis:someOtherOption];
//etc...
The method name alloc is short for "allocate" because it is the method where memory is allocated to the variable. Does the compiler automatically release the memory for sc every time I assign it a new value? I plan on using this method in a project of mine, and I don't want a lot of memory being allocated with all the times I call alloc to assign a new value to mc.
The compiler never calls dealloc. The compiler inserts retain, release and autorelease (more efficient equivalents, really) as necessary to follow the memory management rules.
When the compiler inserts said calls is up to the compiler and the details will change across different compiler versions and different optimization levels.
I.e. you shouldn't need to worry about it in general.
However, autorelease pressure can still be an issue, as can retain cycles. Thus, you should definitely poke about your app with the Allocations Instrument to both measure the high-water mark and make sure your app isn't leaking memory over time.
I read that when using ARC in Objective-C programming in Xcode the dealloc method is called automatically
In Objective-C, you never call -dealloc directly whether or not you're using ARC.
Under what circumstances is it called?
-dealloc is called when an object's retain count drops to zero. That is, it's called when all the objects that had previously asserted "ownership" of the object (by calling +alloc or -retain or -copy or +new) have renounced that ownership (by calling -release or -autorelease).
Does the compiler automatically release the memory for sc every time I assign it a new value?
If you're using ARC (and you should be), the compiler will insert appropriate calls to -retain, -release, etc. so that memory is managed appropriately. That said, you still need to understand how memory management works, and you should be familiar with the material in Advanced Memory Management Programming Guide.
Under ARC, your variable mc will hold a strong reference to only one instance of MyClass at a time, so when you allocate the second one and assign it to the variable, the first one should be getting deallocated, assuming your doThis: method doesn't do something that will create another strong reference to that instance, or that you're not doing anything else in your code that you've omitted that will keep a strong reference.
That being said, it would be a good idea for you to run your app with Instruments to see how much memory your app uses during this. Your instances shouldn't be getting autoreleased, so you shouldn't have to worry about them remaining around until the autorelease pool is drained, but I don't know what you might being doing when you init an instance of the class, or what you might be doing in your doThis: method, so if you're concerned, it's always a good idea to profile it with Instruments for memory allocations and leaks.

Objective C: Memory Leak in non-void instance method

I am getting another memory leak in a non-void instance method that returns a object of class NSMutableArray.
Can someone advise me on how I can fix this leak? I tried to release 'userFollowings' at the end of the method but it's still reporting a leak.
When your are to return an object from a method in which you have either initialized it or retained it, it is common practice to return it autoreleased. That way, the user receiving the object doesn't have to worry about releasing it. So, your final line of code should look like this:
return [userFollowing autorelease];
It probably wouldn't hurt to read a little from the Memory Management Programming Guide to catch up on memory management rules such as this, and there are plenty of other helpful resources out on the web and on this site.
There are a set of conventions used by Cocoa programs that make memory management much less error prone. When a method returns an object, the code that calls it needs to know if it owns it or not.
What it boils down to is that if you are writing a method that returns an object and that method doesn't convey ownership upon the caller by being named something like new, alloc, copy, etc., you need to autorelease it before you return it.
That's what the message you are getting is talking about - "Object returned to caller as an owning reference" means that you're conveying ownership on the calling code. The problem is that your method name indicates otherwise.
If I were to call your method and needed to hang onto the object, I'd call retain on it so that I owned it. I need to do this because your method name implied I wasn't the owner. So long as you are returning an autoreleased object, that's correct. But if you don't autorelease the object, it will end up with a retain count of 2 - once when you allocated it and once when I retained it. When I finally get round to releasing it, it will still have a retain count of 1, and will never be deallocated from memory, resulting in a memory leak.
The problem is that userFollowings never gets released. Try ending with
return [userFollowings autorelease];
Try this:
NSMutableArray* userfollwings = [[[NSMutableArray alloc] init] autorelease]

What is the difference between releasing and autoreleasing?

I still have some unclear understand about release and autorelease. What are the difference between both of them? I have this code. For facebook connection. I crash it sometimes when I go to Facebook login, I doubting maybe it is because I don't release the object nicely.? Thanks for any helps
if (_session.isConnected) {
[_session logout];
} else {
FBLoginDialog* dialog = [[[FBLoginDialog alloc] initWithSession:_session] autorelease];
[dialog show];
}
The Memory Management Programming Guide for Cocoa will soon be your best friend. In brief, object instances in Cocoa are memory managed using reference counting (unless, of course you're using garbage collection on OS X). An object indicates that it wants to 'retain' an ownership interest in an other instance--keep it from being deallocated--by sending it a -retain message. An object indicates that it wants to release that interest by sending the other instance a -release message. If the number of objects that have 'retained' and ownership interest in an object drops to 0 (i.e. when the last of the owning instances sends a -release message), the instance with a 0 retain count is deallocated.
It's sometimes convenient to say "I want this instance to be released some time in the future". That's the purpose of -autorelease. Sending an -autorelease message adds the receiver to the current NSAutoreleasePool. When that pool is drained, it sends a -release message to all the instances in the pool. An NSAutoreleasePool is automatically created at the start of each iteration of each thread's run loop and drained at the end of that iteration. Thus, you can do something like this in a method:
- (id)myMethod {
return [[[MyObject alloc] init] autorelease];
}
The caller of this method will get back an instance that they can -retain if they wish to keep it. If they don't retain it, it will stick around at least until the enclosing autorelease pool is drained:
- (void)someOtherMethod {
...
id instance = [obj myMethod];
... // do more with instance, knowing that it won't be dealloc'd until after someOtherMethod returns
}
Releasing means you release that right away.
Autoreleasing means you want the variable to be released on the next autorelease pool.
You use autorelease when you want to keep retaining the variable but don't want to create a memory leak. You use release when you don't need the variable anymore.
Sample:
- (NSNumber *)return5 {
NSNumber * result = [[NSNumber alloc]initWitnInt: 5];
[result autorelease];
return result;
}
Why do we use autorelease there?
If we use [result release] instead, variable result will be destroyed AT that time. Which means that the returned value will be garbage.
If we do not release at all, variable result will be hold FOREVER incurring memory leak.
We can tell every caller to the function to release result but that would be a headache and prone to error.
So we use autorelease. We mark the variable to be released on the next autorelease pool. Basically we mark the variable to be released near the alloc. Hence the mantra alloc is paired with release in the same function holds all the time.
Actually, you'll do fine changing all release into autorelease. Your memory use won't be efficient, however, the effect is minimal. All variables, in all programming language is effectively autoreleased.
Anyway, use ARC.
background discussion:
objective-c is reference counted, so objects are deleted when the reference count reaches 0. release reduces the reference-count immediately, autorelease reduces it when the autorelease-pool is popped
when to use:
use autorelease when allocating the object if
you do not need it after the current function
it will be retiained by some other objet/function and will be released by a later by the retaining code
when the logic of the current function is tricky, so you would have to send release in a dozen different places before doing a return
use "manual" release
to revert a previous retain (in case you are implementing a library)
if you need precise control of freeing objects (e.g. they use lots of memory or the autorelease pool will not be popped for some time)
but really my freand:
read the Memory Management Programming Guide for Cocoa as suggested by Barry and run your code with instruments (zombies and leaks) often to catch any and almost all memory management errors.
Erik
According to the Memory Management Programming Guide for Cocoa:
The autorelease method, defined by
NSObject, marks the receiver for later
release. By autoreleasing an
object—that is, by sending it an
autorelease message—you declare that
you don't want to own the object
beyond the scope in which you sent
autorelease.
Also:
The autorelease method thus allows
every object to use other objects
without worrying about disposing of
them.

Accessor method object management?

After reading the Memory Management Guide I am trying to get my head around what is happening here My understanding "so far" is ...
- (EngineClass *)engine {
return [[engine retain] autorelease];
}
I am returning a pointer to an Engine object.
The retain count of the object is incremented to record we are making a new pointer to the object
Balance the above retain by specifying an autorelease at some future point.
Am I on the right track?
cheers -gary-
I'm not sure I'd say the retain is "to record we are making a new pointer to the object."
The retain-autorelease pair is there to indicate that there's another object interested in the return value, so it needs to stick around at least that long, but the other object doesn't properly own the return value. Without the retain, if the object performing this method is deallocated immediately afterward, the engine might not have any other owners and would also be deallocated immediately. That's not the expected behavior. Doing it this way causes the object's ownership not to go away until the autorelease pool is drained.