Search code examples
objective-cmemory-leaksinstance-variables

Objective-c instance variable memory issues with ARC on


I have a largish objective-c iPhone project that runs fine, except that the memory use constantly increases while the app is in use, and never decreases. It does not increase while the app is not being actively used.

I have an almost identical Android app in Java that does not have this issue. After a lot of googling and experimenting I think the issue is that all of my class variables are instance variables, i.e they are declared in the .m files like below, and accessed using getters and setters.

@implementation SomeClass{
    NSString *someVariable;
    AnotherClass *anotherVariable;
}

There are a number of cases where two objects will have references to one another via the instance variables. I believe this is where the memory issues come from as I have read that the ARC will count each of these objects having 1 remaining pointer to them (from the other object) and therefore never release either from memory.

Ideally I'd like a solution that does not require moving all variables to the .h file, and also does not require changing the definition per variable, i.e I want a solution I can apply to all variables, although I don't know if this is possible. I think I am right in saying instance variables are 'strong', in that they increment the ARC reference count of that object, can I make all my instance variables 'weak', and if so would this be a good or bad idea?


Solution

  • I have solved by putting __weak or __unsafe_unretained before instance variables that reference a parent class if that parent has a reference to the child. Using either means that the reference count for the parent object does not increase.

    Use __unsafe_unretained if you want an exception to be thrown when you access the variable but the object has been release. Use __weak if you don't want an exception, the variable will become nil when the object is released.

    @implementation SomeClass{
        NSString *someVariable;
        ChildClass *childVariable;
        __unsafe_unretained ParentClass *parentVar;
        __weak AnotherParentClass *AnotherParentVar;
    }