Objective-C memory details - objective-c

in my objective-c program (or, maybe, in debugging utility) I get a bizarre behavior.
I defined, but not allocated or initialized 4 instances of some class (let it be "Rectangle"):
Rectangle *left, *right, *bottom, *upper;
Right after this line, I expect that for all of my four objects will be null pointers (debugging in Xcode), but for one of them (concretely "upper") exist point to some memory location, and his properties is initialized with random values.
Does it normal behavior? If so, please explain me why. (I am a bit new to objective-c programming)

Objective C does not (in general) guarantee that stack values are zeroed. It does guarantee that all ivars in an object are zeroed. Also, under ARC it does zero stack vars that it knows are objects. So the behavior you are seeing is correct assuming you are not using ARC.
In general, even if you are in an environment that zeros the value you should explicitly zero it in case your code gets reused somewhere else. If there is a constraint your code needs to work you should either satisfy it, test for it at runtime, or test for it at compile time (assert()).
As for why this is the case, it is that way because C behaves that way, and C traditionally has done it because it is bare metals and prefers to let the compiler have a lot of liberty in order to do performance optimizations. Objective C only differs in places where it needs to in order to support its own (supplemental) functionality.

Pro-tip: Never assume anything. It is good practice to initialize all your variables to a known value; in this case, nil.
If you are coming from another high-level language that does initialize variables for you, well... this isn't that language. :-)

You should do this...
Rectangle *left = nil;
Rectangle *right = nil;
Rectangle *bottom = nil;
Rectangle *upper = nil;
which is the same as
Rectangle *left = nil, *right = nil, *bottom = nil, *upper = nil;

Use ARC, its amazing as memory management isn't handled by you anymore!

Related

ARC __bridge modifiers demystified

I was asked recently by one of my friends about the new bridge modifiers that became active under ARC. He asked me if I knew which ones to use in specific times and what the difference between the different __bridge modifiers were. He asked me,"so how do they work, when do I use them, how do I use them , and how do they work "under the hood" "?
Note: This was supposed to be a "Share your knowledge" type of question, where I answered the question myself, but I'm not sure I set it up properly.
Because I learned what they were and how they operated just recently, I want to share with anyone else who wishes to learn about the __bridge modifiers under ARC which can be a source of confusion due to the fact that toll-free bridging used to be accomplished with a simple cast.
It used to be that if you wanted to, say, cast your NSArray object to a CFArrayRef for any purpose, it could be done with a simple cast like so:
NSArray* myArray = [NSArray alloc]initWithObjects:....]; //insert objects
CFArrayRef arrayRef = (CFArrayRef) myArray;
In this case, maybe you had an NSArray of colors and needed to cast it to CFArrayRef for using it with CoreGraphics to draw a gradient.
However with ARC, this will no longer work for you and you will receive this error:
Well what the heck does this mean!?!
Well it turns out, ARC doesn't like it when you do this kind of cast and will even give you a few "Fix it" solutions, which all seem to have that same __bridge keyword in them, so let's get right to them!
Under ARC we have 3 main __bridge modifiers:
__bridge
__bridge_retained ( which is partnered by the CFBridgingRetain function)
__bridge_transfer (which is partnered by the CFBridgingRelease function)
So we'll begin with __bridge. What is it? __bridge is just another way of saying: "Hey compiler, just give me my darn casted object!". The compiler will be happy to do so and return to you a casted object of your liking!
However, because you wanted a "freely" casted object like that, YOU are still responsible of releasing the memory for the originally allocated object. In this case, if I were to do this:
NSArray* myArray = [NSArray alloc]init];
CFArrayRef arrayRef = (__bridge CFArrayRef) myArray;
I am still responsible for releasing the myArray memory because it was the originally allocated object. Remember, __bridge just tells the compiler to perform the cast!! And because I am compiling under ARC, I don't explicitly have to call [-release] on the myArray object, ARC will do it for me!
Note, that the __bridge modifier works both ways! (Hence, toll-free bridging) and you can just as easily cast a CF object to an NS object the same way ( that is toll-free bridgeable!) like so:
CFArrayRef arrayRef; // allocate this arrayRef and give it a value later on
//... amazing code.....
NSArray* myArray = (__bridge NSArray*)arrayRef;
But since the CF object would be the originally allocated object, I must call CFRelease(whatever);
Now let's move on to __bridge_retained and its partner in crime CFBridgingRetain() . This __bridge modifier is geared EXPLICITLY towards transferring the ownership of an NS object TO A CF OBJECT (So we'll be expecting to manually CFRelease(whatever) this due to it being a CF type object)
Meaning, if I were to do my old scenario again, but this time with __bridge_retained:
NSArray* myArray = [NSArray alloc]initWithObjects:....]; //insert objects
CFArrayRef arrayRef = (__bridge_retained) myArray;
the arrayRef object now has explicit ownership of the memory that used to be owned by the myArray pointer. Because now the CF type has ownership, I must release it myself using CFRelease(whatever);
So what role does the CFBridgingRetain() function play in all this chaos? It plays the same exact role as doing the cast we just talked about! Let's take a look at the function prototype for CFBridgingRetain:
CFTypeRef CFBridgingRetain(id x);
We can see, it pretty much just simplifies the whole (__bridge_retained) notion into one function! We're gettting back a CF object after "inputting" an NS type object! Radical! Yes, I know this is awesome! Too much coolness to take in one sitting! And yes, it also performs the memory "ownership" transfer.. how awesome!
And last, but by no means least, __bridge_transfer and the almighty CFBridgingRelease() !
__bridge_transfer works almost like the opposite of __bridge_retained. The __bridge_transfer modifier transfers the ownership of a CF object type to an NS object type.
So let's refer to the example that's been used throughout this to dissect it:
NSArray* myArray = [NSArray alloc]initWithObjects:....]; //insert objects
CFArrayRef arrayRef = (__bridge_retained) myArray;
// at this point, arrayRef holds the ownership
// Let's add this new line to change things up a bit:
NSArray* otherArray = (__bridge_transfer NSArray*)arrayRef;
So what does this awesome little program that we just wrote exactly do?
Step 1: We allocated an NSArray
Step 2: We passed the ownsership of the array to the arrayRef object
// Before we continue to step 3, let's understand at this point arrayRef is the owner
Step 3: We re-transfer the ownership that USED to be owned by arrayRef back to an NSArray*
Because at this point, the otherArray pointer is the owner, it would seem sort of natural at this point to say [otherArray release] when we're done, right? Well this is where ARC kicks in and will take care of releasing that array for you!
And did you know it gets cooler? This __bridge modifier's awesome partner in crime:
CFBridgingRelease()
makes it that much cooler! CFBridgingRelease has this function prototype:
id CFBridgingRelease(CFTypeRef x);
And we see, this is exactly the same thing that happens when we cast with __bridge_transfer. And this function also transfers the ownership to the NS object! This is just fantastic!
Using the CFBridgingXXX functions maybe can make a little more sense at first, due to the fact that many objective-c programmers still have the notion of the NARC rule:
Everything that has been called with:
N ew
A lloc
R etain
C opy
must have a balancing -release call
So doing this:
NSArray* myArray = [[NSArray alloc]init];
// there's the A of NARC!
//(cleaned by ARC)
CFArrayRef arrayRef = CFBridgingRetain(myArray); // there's the R of NARC!!
//NSArray* other = CFBridgingRelease(arrayRef); // cleaned up by ARC
Can make the process of learning the __bridge casts easier due to the fact that the retain was matched with a release
If all this still may be confusing, think of it this way: You are a pointer to any NS object type. For the sake of consistency, let's say you're an NSArray pointer, that right now isn't pointing to anything. So you can sort of imagine that you, as the nil pointer, are standing in a bathroom with the lights turned off. ( The lights turned off represents that you aren't pointing to anything).
Then, later on in code, your programmer decides to assign you to a new NSArray. i.e, he/she says this:
you = [[NSArray alloc]init];
Suddenly, the lights in the bathroom you were standing in, have turned on! You're pointing to an object! Now in normal program execution, when you're done using the object, you release it. So in this case, when you're done using the bathroom, you turn the lights off.
But the program you're in, unfortunately, isn't very "normal". The programmer decided to use some CoreFoundation objects! Bleh!
And he writes this line of code:
CFArrayRef other = (__bridge_retained CFArrayRef) you;
So now what happens is that, another person walks into the bathroom at the same time you leave. Out of politeness, you don't turn the lights off because there's another person using the restroom and is responsible for turning the lights off when he/she leaves
In this case, because the new owner of the restroom is a CF object, the programmer must manually release it.
But what if he/she were to write this:
CFArrayRef ref = (__bridge CFArrayRef) you;
what happens here is that, another person just barged into the same restroom as you without even asking! How rude! On top of that he expects you to clean up after him too! So you, being a gentlemen/lady turn off the lights when both of you finish.
However, since you are an NS type object, ARC comes and cleans it for you :)
And finally, what if the programmer writes this:
you = (__bridge_transfer NSArray*)arrayRef;
What happens here is the exact opposite of the first scenario. Instead of you leaving the restroom at the same time as someone enters, you're the one who enters while the other person leaves
The same memory management rules apply. Since you took over "owning" the restroom, you must manually turn off the lights. And because you're an NS type object, ARC will do it for you... again :) Isn't ARC such a beauty!
I know this may seem a bit intimidating and confusing at first, but just work your way through it, read it again and you'll find out how incredible this ARC mechanism works!
Thanks everyone for reading! Hope this helped :)
Thanks to #rob mayoff and # Krishnabhadra for
all the extra help and suggestions!

ARC and __unsafe_unretained

I think I have a pretty good understanding of ARC and the proper use cases for selecting an appropriate lifetime qualifiers (__strong, __weak, __unsafe_unretained, and __autoreleasing). However, in my testing, I've found one example that doesn't make sense to me.
As I understand it, both __weak and __unsafe_unretained do not add a retain count. Therefore, if there are no other __strong pointers to the object, it is instantly deallocated (with immutable strings being an exception to this rule). The only difference in this process is that __weak pointers are set to nil, and __unsafe_unretained pointers are left alone.
If I create a __weak pointer to a simple, custom object (composed of one NSString property), I see the expected (null) value when trying to access a property:
Test * __weak myTest = [[Test alloc] init];
myTest.myVal = #"Hi!";
NSLog(#"Value: %#", myTest.myVal); // Prints Value: (null)
Similarly, I would expect the __unsafe_unretained lifetime qualifier to cause a crash, due to the resulting dangling pointer. However, it doesn't. In this next test, I see the actual value:
Test * __unsafe_unretained myTest = [[Test alloc] init];
myTest.myVal = #"Hi!";
NSLog(#"Value: %#", myTest.myVal); // Prints Value: Hi!
Why doesn't the __unsafe_unretained object become deallocated?
[EDIT]: The object is being deallocated... if I try to substitute lines 2 - 3 with NSLog(#"%#", myTest); the app crashes (and an overridden dealloc in Test is being called immediately after the first line). I know that immutable strings will continue to be available even with __unsafe_unretained, and that a direct pointer to the NSString would work. I am just surprised that I could set a property on a deallocated object (line 2), and that it could later be dereferenced from a pointer to the deallocated object it belonged to (line 3)! If anyone could explain that, it would definitely answer my question.
I am just surprised that I could set a property on a deallocated object (line 2), and that it could later be dereferenced from a pointer to the deallocated object it belonged to (line 3)! If anyone could explain that, it would definitely answer my question.
When the object is deallocated it is not zeroed. As you have a pointer to the deallocated object and the property value is stored at some offset to that pointer it is possible that storing and retrieving that property value will succeed after deallocation, it is also quite possible that everything will blow up for some reason or other.
That your code works is quite fragile, try debugging it with "Show Disassembly While Debugging" and stepping through, you'll probably hit an access violation, or take down Xcode itself...
You should never be surprised that strange things happen in C, Objective-C, C++ or any of the family; instead reserve your surprise for so few strange things happening!
Because the constant string in objc is a constant pointer to a heap address and the address is still valid.
edited after comment:
Maybe because the memory at the test objects address hasn't been overwritten and still contains that object? Speculating....
You can see when Test is deallocated by implementing its -dealloc method and adding some simple logging.
However, even if Test is deallocated immediately, the memory it occupied in RAM may remain unchanged at the time you call myVal.
#"hi!" produces a static global constant string instance that is, effectively, a singleton. Thus, it'll never be deallocated because it wasn't really allocated in the first place (at least, it really isn't a normal heap allocation).
Anytime you want to explore object lifespan issues, always use a subclass of NSObject both to guarantee behavior and to make it easy to drop in logging hooks by overriding behavior.
Nothing strange there…
You need to have at least 1 strong reference to object to keep it alive.
Test * anTest = [[Test alloc] init];
Test * __weak myTest = anTest;
myTest.myVal = #"Hi!";
NSLog(#"Value: %#", myTest.myVal); // Prints Value: (Hi)

Convert method that returns an autoreleased CGColor to ARC

I'm in the process of converting my project to using ARC. I have a category on NSColor with a method that returns an autoreleased CGColor representation:
#implementation NSColor (MyCategory)
- (CGColorRef)CGColor
{
NSColor *colorRGB = [self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
CGFloat components[4];
[colorRGB getRed:&components[0]
green:&components[1]
blue:&components[2]
alpha:&components[3]];
CGColorSpaceRef space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGColorRef theColor = CGColorCreate(space, components);
CGColorSpaceRelease(space);
return (CGColorRef)[(id)theColor autorelease];
}
#end
What is the correct way to do this with ARC? I don't want to return a retained CGColor.
The ARC converter in XCode suggest using
return (CGColorRef)[(__bridge id)theColor autorelease];
but that results in the following error message:
[rewriter] it is not safe to cast to 'CGColorRef' the result of
'autorelease' message; a __bridge cast may result in a pointer to a
destroyed object and a __bridge_retained may leak the object
Essentially it's because there is no good way to convert the following code in ARC:
CGColorRef a = ...;
id b = [(id)a autorelease];
CGColorRef c = (CGColorRef)b;
// do stuff with c
The converter removes -autorelease and adds some bridged casts, but it gets stuck:
CGColorRef a = ...;
id b = (__bridge_transfer id)a;
CGColorRef c = (__bridge_SOMETHING CGColorRef)b;
// do stuff with c. Except the compiler sees that b is no longer being used!
But what should the migrator choose to do for __bridge_SOMETHING?
If it picks __bridge, then b is no longer used so the compiler can immediately release it. This crashes.
If it picks __bridge_retained, then ownership is transferred back to "CF-land", but the original code assumed that the object would be owned by the autorelease pool. The code now leaks.
The problem is that ARC forbids calling -autorelease but does not have a documented method to guarantee that an object is added to the autorelease pool — the only good reason to do this to return an autoreleased CF type from a method, but plenty of UIKit classes have CF-typed properties (and MKOverlayPathView has an atomic CGPathRef property which must return an autoreleased value).
This is one of the tricky bits of ARC that I really wish was better documented.
There are a few hoops you can jump through which might work with varying degrees of success. In order of increasing ickiness:
Define a CFAutorelease() function in a file compiled without ARC (add -fno-objc-arc to the compiler flags in target settings → Build Phases → Compile Sources). I leave this as an exercise to the reader. This works because ARC code needs to interoperate with MRC code. This is probably the cleanest solution. (This is bound to attract a comment saying that it shouldn't use the CF prefix, but as long as you don't see a link error, C symbol name collisions are generally safe because the of the "two-level namespace" introduced in 10.3 or so.)
Various hoops to send it an -autorelease message or equivalent. All of these are a bit messy because they rely on "fooling" ARC, except the last one which assumes id is ABI-compatible with void*. They're also probably slower than the above because they need to look up a class/selector (objc_lookUpClass() and sel_registerName() might be faster or even optimized away, but I wouldn't bet on it).
return (__bridge CGColorRef)[(__bridge id)theColor performSelector:NSSelectorFromString(#"autorelease")]
[NSClassFromString(#"NSAutoreleasePool") addObject:(__bridge id)theColor]
return theColor;
return (__bridge CGColorRef)((id(*)(id,SEL))objc_msgSend)((__bridge id)theColor,NSSelectorFromString(#"autorelease"));
return ((void*(*)(void*,SEL))objc_msgSend)(theColor,NSSelectorFromString(#"autorelease"));
Force it to be added to the autorelease pool by assigning to an __autoreleasing variable that the compiler can't optimize away. I'm not sure if this is guaranteed (in particular, something similar to objc_autoreleaseReturnValue() and objc_retainAutoreleasedReturnValue() might be possible, but I think this is unlikely since it would slow down the common case of (NSError * __autoreleasing *)error).
-(id)forceAutorelease:(id)o into:(id __autoreleasing*)p
{
*p = o;
return p;
}
-(CGColorRef)CGColor
{
...
CGColorRef theColor = CGColorCreate(...);
CGColorSpaceRelease(space);
id __autoreleasing temp;
return (__bridge CGColorRef)[self forceAutorelease:(__bridge_transfer id)theColor into:&temp];
}
(It also might be possible for the compiler/runtime to co-operate and use static dispatch/inlining until the relevant methods are overridden, but that seems tricky and not without significant overheads of its own.)
Use a typedef with __attribute__((NSObject)). This is the most confusingly documented parts of the ARC spec, but something like this seems to work:
typedef CGColorRef MyCGColorRef __attribute__((NSObject));
-(MyCGColorRef)CGColor
{
...
return (__bridge MyCGColorRef)(__bridge_transfer id)theColor;
}
I think you need two bridges for this to work (one to transfer ownership to ARC and another to); if you simply return theColor; I suspect it is leaked. From my reading of the docs, you ought to just need (__bridge_transfer MyCGColorRef) because it's converting from a non-ARC pointer (CGColorRef) to an ARC pointer (MyCGColorRef), but that makes the compiler complain. Alas, the docs do not give any examples of how to use __attribute__((NSObject)) typedefs.
Note that you do not need to change the return type in the header. Doing so may enable autoreleased return value optimization, but I'm not sure how the compiler handles the conversion from MyCGColorRef to CGColorRef. Le sigh.
CGColor is a Core Foundation object. You should not attempt to use autorelease with it. Instead, you should rename your method copyCGColor and return a retained object.
Auto-releasing is an Objective-C concept. It does not exist at the Core Foundation level.
Since CGColor is not toll-free bridged to any Objective-C class, it is very weird to try to autorelease it (even if that might work).
Update a few years later
There is now CFAutorelease() at the CoreFoundation level (available since Mavericks and iOS 7).
Starting with OS X 10.9 or iOS 7 you can just use CFAutorelease() (declared in CFBase.h).
Indeed, in manual memory management you can retain, release and autorelease any CoreFoundation object, because they all are toll-free bridged to at least NSObject.
Since ARC forbids use of manual memory management, we should somehow tell hint the compiler what to do. One way is to name your method - (CGColorRef)copyCGColor; so the compiler will know the method returns object with +1 retain count.
However if you are like me and prefer plain "CGColor" for such methods, you can just append __attribute__((cf_returns_retained)) to the method definition:
#interface NSColor (MyCategory)
- (CGColorRef)CGColor __attribute__((cf_returns_retained));
#end
I think you want to use __bridge_transfer in this case.
Docs

Strict Type Checking in Objective-C via Macros

Occasionally, during development/debugging, I want to ensure that an object is of a certain type:
PageTopBottom *newPage = [notification object];
assert([newPage isKindOfClass:[PageTopBottom class]]);
which I've worked into this
#define assertType(_var_, _class_) assert([_var_ isKindOfClass:[_class_ class]])
and
PageTopBottom *newPage = (id)[notification object];
assertType(newPage, PageTopBottom);
but now I'd like to, if possible, just use
assertType(newPage)
Is it possible to get information about a variable's declared type from the variable?
I'm not positive that I'm framing the question correctly, but any answer that gets me to be able to assertType with one parameter would be great.
Is it possible to get information about a variable's declared type from the variable?
No. By the time the program is running, that information is lost. In your case, newPage is just a 32 or 64 bit number that points to a bit of memory that holds an Objective-C object.
I think your original unmacro'd version is the right thing to do here:
assert([newPage isKindOfClass:[PageTopBottom class]]);
That perfectly documents the assumption you are making i.e. that you assume newPage is an instance of PageTopBottom or one of its subclasses and it's completely clear to anybody who understands Objective-C. Your macro version slightly obfuscates that, in that somebody coming across it in the code might beleive it is asserting that newPage is a PageTopBottom and not one of its subclasses (you could change the name of the macro to prevent that, I suppose, but I just wouldn't bother).
Edit
What you could do is combine the declaration and assertion in one:
#define DECLARE_AND_ASSERT_IS_KIND_OF_CLASS(T, V, I) T* V = (T*)(I); assert([(V) isKindOfClass: [(T) class])
which would work like this:
DECLARE_AND_ASSERT_IS_KIND_OF_CLASS(PageTopBottom, newPage, [notification object]);
Hmm, with Objective-C++ there are two options:
Write a template function
template void assertType(T* obj) { ... }
For a pointer X* x, use NSClassFromString([NSString stringWithUTF8String:typeid(*x).name()]).
Without using C++, you might be able to use GCC extension typeof, but I'm not sure if [typeof(*x) class] is a legit operation...
The preprocessor only processes text; it has no knowledge of type, which is why it's sometimes considered 'dangerous'. The only way I could see doing it is wrapping the variable declarations in a macro, which I would strongly advise against, and probably wouldn't actually cut down on the code or complexity.
Also, shouldn't you check the type before casting?

How to use the unary pointer operator (*) in C?

I'm reading a book called Java and C: Key Differences, Learn Objective-C for Java Developers. (my background is C#/Java so the concept of pointers and managed memory is new to me, so please bear with me)
In chapter 2, it explains pointers with this example:
int i = 1;
int *iptr;
iptr = &i;
*iptr = 2;
I understand the above, where *iptr is a pointer, it is assigned the memory location of i, also from the pointer iptr we can access the value iptr points to with the *iptr syntax.
Further down the book there is the following snippet:
//..
NSMutableString *z = [[[NSNutableString alloc]init] autorelease];
[z appendString:#"Zombie "];
//...
From my understanding of chapter 2, the line [z appendString:#"Zombie "] should have been [*z appendString:#"Zombie "] instead, as we want the actual NSMutableString, not to its pointer, to be sent the message appendString!? I know I'm wrong and there is something that I'm missing, please point me to the right direction.
Many thanks,
Giuseppe
In Objective-C, you always work with pointers to objects (you can't create an object on the stack). Messages are always passed to pointers (although that's only an abstraction -- more complicated things are done at the runtime level).
The simple answer is that the Objective-C syntax is not the same as plain C language.
Yes, an Obj-C object is defined with the normal C syntax since it's actually a pointer to a structure but is then used without the * operator while dealing with Objective-C instructions..
Actually nothing forbids the semantics of Objective-C from sending a message to an object through its pointer, so simply don't worry.
In any case this applies to every object but there are many typedefs (for example NSInteger) that wraps primitive o structured C types. They can be used in C either by directly working with them onto the stack, either by allocating them.
Probably you are not aware that
NSMutableString *z = [[[NSNutableString alloc]init] autorelease];
is the abreviated form of
NSMutableString *z;
z = [[[NSNutableString alloc]init] autorelease];
Probably now is clearer.
As mipadi said, in Objective-C you always deal with pointers to objects and not real objects (like sometimes in C++ for example)
The bracket notation [obj message] implies that obj is a pointer to an object. Thus * is to be expressed.