Application crashes after upgrading Xcode to 4.5. Assigning a saved object to unsafe_unretained

In my class, I have a dispatch_queue_t property declared as follows:

 @property (nonatomic, assign) dispatch_queue_t queue; 

Then in my init method I do:

 - (id)initWithServerUrls: (NSString*)serverUrls { if (self = [super init]) { _queue = dispatch_queue_create("com.xxx.my_send_queue", DISPATCH_QUEUE_SERIAL); } return self; } 

In Xcode 4.4.1, it worked and did not cause problems (application checked + in appstore). Now, after I upgraded to Xcode 4.5, the application crashes with EXC_BAD_ACCESS , and Xcode gives me a warning on this line:

Assigning a saved object to unsafe_unretained; the object will be released after the appointment

Apple has updated the compiler in Xcode 4.5 from LLVM 4.0 to LLVM 4.1, but I don’t know why my code is crashing right now.

I went through the code, and the accident occurred immediately after this line. Do you have any ideas what might be wrong and how can I fix it?

DECISION:

I managed to get it to work with both SDKs. I just added:

 #if OS_OBJECT_USE_OBJC @property (nonatomic, strong) dispatch_queue_t queue; // this is for Xcode 4.5 with LLVM 4.1 and iOS 6 SDK #else @property (nonatomic, assign) dispatch_queue_t queue; // this is for older Xcodes with older SDKs #endif 

Hope someone finds this helpful

+6
source share
1 answer

Firstly, if your target platform is 5+, then I highly recommend building with the iOS 5 SDK. Building with a later SDK and installing "target" may work, but you have a lot of problems (not least because you do not get the help of the compiler to find places where you used unsupported methods). So answer 1: you need iOS 5, build against iOS 5, and that doesn't matter.

In iOS 6, dispatch_queue_t is an ObjC object. This is a big improvement. This means that you can just create strong properties for it, and ARC will take care of the rest. If you are targeting iOS 6, this should work.

If you need to create the same code for iOS 5 and iOS 6, then you need to know what it is that you can put in memory management when you need it, and leave it when you don't. The correct test to use is #if OS_OBJECT_USE_OBJC . Remember that this is a compile time check. This is only applicable for working with the code you want to write against different SDKs. For this SDK, the behavior will occur one way or another.

Regarding "unsafe_unreveded" versus "asking" confusion: in this case it is one and the same. "assign" applies only to non-objects. "unsafe_unretained" is that "assignment" is converted when applied to objects. And in iOS6, dispatch_queue_t is an object.

Another workaround, especially if you really want to keep the old memory management code when building using the iOS 6 SDK. You can pass -DOS_OBJECT_USE_OBJC=0 compiler. This will abandon the new model. But I would recommend this as a last resort. See os/object.h in the SDK for more details. (Cmd-Shift-O, object.h)

+13
source

Source: https://habr.com/ru/post/925842/


All Articles