I am trying to create a structure that has several different variable of different types in it.
several of the types are of NSString, but trying to do this was causing an error
ARC forbids Objective-C objects in structs or unions
so having read about the error I see its sensible to add
__unsafe_unretained
before the NSString declaration, However I have no idea what the ramifications of this will be, I have had a quick read around and found this detailed post about the differences of
- __strong
- __weak
- __unsafe_unretained
however it was still abit vague about whats going on with a NSString thats in a struct with __unsafe_unretained infront of it and was hoping someone can tell me whats going on and what I need to think about in the future regarding memory and stopping any leaks.
any help would be appreciated.
Suppose, under ARC, you could declare a struct like this:
Then you might write code like this:
Problem:
mallocdoesn’t zero-fill the memory it returns. Sothing->someObjectis some random value – not necessarily NULL. Then you assign a value to it like this:Under the covers, ARC will turn that into code like this:
The problem here is that your program just sent
releaseto some random value! Your app will probably crash at this point.You might say that ARC should recognize the call to
mallocand take care of settingsomeObjectto NULL to prevent this. The problem is thatmallocmight be wrapped in some other function, like this:OK, now ARC has to know about your
myAllocatefunction too… and that might be inside some static library that you got as a binary.Your app might even have its own memory allocators that recycle old allocations without using
freeandmallocevery time. So even changingmallocto zero-fill the memory before returning it would not work. ARC would have to know about any custom allocators in your program.It would be very, very hard to make this work reliably. So instead, the creators of ARC just gave up and said “Forget it. We’re not going to let you put
__strongand__weakreferences in structs.”That’s why you can only put an object pointer into a struct if you use
__unsafe_unretainedto tell ARC “Don’t try to manage ownership of the object that this references.”You can try to use a struct containing
__unsafe_unretainedobject references, perhaps usingCFRetainandCFReleaseto manually retain and release them. Then you can create an array of such structs. This is error-prone, so you should only do it if the profiler tells you that it’s critical for performance.Instead, just create a new Objective-C class instead of a struct. Give the class an
@propertyfor each field you would have put in the struct. The use anNSMutableArrayto manage an array of instances of this new class.