Search code examples
iosobjective-cautomatic-ref-countingobjective-c-runtimeunsafe-unretained

malloc object lifetime with __unsafe_unretained typecast


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.

  • Does Class behave differently from other kinds of Objective-C data types? Should I expect something else from it?
  • What kind of pointer is 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.
  • Are there strong pointers to the objects in the array at all, or are the objects themselves strong pointers? If not, does ARC still work, or should I revert to some MRC conventions?
  • Will there be an automated call to dealloc? When, and how can the compiler ensure that that happens?
  • Is it better practice to set 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?

Solution

  • 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.