I'm new to Objective-C and ARC, and have been searching and reading for hours without finding an answer. The code does what I want it to do, but I want to know that it doesn't rely on favorable conditions. Here's a simplified version of my code:
+(void)foo {
Class *classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * someValue);
// Perform work without complicated memory management
free(classes);
}
I can't do much about the structure I'm allocating. It's filled by objc_getClassList. Unfortunately, Apple doesn't seem to have updated their documentation to explain how to do this under ARC. The typecast above is partly conceived by looking at examples, but it still makes me nervous.
One of my concerns is that if I would have allocated space for a "regular" object, then dealloc
would have been called when the variable goes out of scope, which would have happened after free
is called. But I don't think that's exactly what's going on here.
Class
behave differently from other kinds of Objective-C data types? Should I expect something else from it?classes
? I guess it references an array of unknown size (a non-object pointer), but ARC still cares about it since the code won't compile without that cast. It looks like a strong pointer, but I don't know what it would be a strong pointer to.dealloc
? When, and how can the compiler ensure that that happens?classes
to NULL
, and only then do the call to free
? Or should I iterate over the array and do something about every object, such as setting them to nil
?you are allocating an array of struct pointers (Class == pointer to a struct), which will be filled with pointers to the Classes registered to the runtime. This pointers will not be released/dealloced etc. as long as your application runs.
You are not allocating any-classes, you are allocating space to hold pointers to this classes. Your code is totaly fine, and __unsafe_unretained
is exactly what you want. It tells ARC you are holding a pointer to an Object you are not owning, and so prevent it from trying to release it at the end of the scope of your variable.