Release the object in a project other than ARC, the object is declared in the ARC library

Well, I'm working on a project other than ARC, but I use the Philipp Kyeck socket library , which is written using ARC. I use the method described in this to combine a non-ARC project and an ARC library.

In my ViewController file, I initialize the socket using

SockIO *chatSockIO = [[SocketIO alloc] initWithDelegate:self]; 

and when I need to disconnect, I call

 [chatSockIO disconnect]; 

which causes the delegate method socketIODidDisconnect to fire.

 - (void) socketIODidDisconnect:(SocketIO *)socket{ [chatSockIO release]; ==> is this call needed? } 

Now my question is about the [chatSockIO release] . Should we need to free an object that is itself defined in ARC mode, but used in a project without ARC?

Now that I tried the release, I got an exception saying

 -[SocketIO retain]: message sent to deallocated instance 0x6fec370 

but when I commented on this line, I get a memory leak and dealloc in my library object that doesn't call at all

Battle time !!

Forget the library I mentioned, the error in my code and the leak. What is the usual practice of using an object defined using the ARC method in a project other than ARC. Should I isolate it, or should I isolate and release it after use?

EDIT: additional information.

I run a zombie tool in an accident, and that is what he had to say. It shows a call to highlight and release functions.

 # Address Category Event Type RefCt Timestamp Size Responsible Library Responsible Caller 0 0x72d5da0 SocketIO Malloc 1 00:09.700.274 64 MyProject -[MyViewController sendRequestForSocketIOPush] 1 0x72d5da0 SocketIO Retain 2 00:09.700.317 0 MyProject -[SocketIO initWithDelegate:] 2 0x72d5da0 SocketIO Release 1 00:09.700.320 0 MyProject -[SocketIO initWithDelegate:] 3 0x72d5da0 SocketIO Retain 2 00:09.700.440 0 Foundation -[NSURLConnectionInternal initWithInfo:] 4 0x72d5da0 SocketIO Retain 3 00:10.413.717 0 Foundation -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] 5 0x72d5da0 SocketIO Release 2 00:10.413.761 0 Foundation -[NSURLConnectionInternalConnection invokeForDelegate:] 6 0x72d5da0 SocketIO Retain 3 00:10.413.797 0 Foundation -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] 7 0x72d5da0 SocketIO Release 2 00:10.413.811 0 Foundation -[NSURLConnectionInternalConnection invokeForDelegate:] 8 0x72d5da0 SocketIO Retain 3 00:10.413.816 0 Foundation -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] 9 0x72d5da0 SocketIO Release 2 00:10.415.087 0 Foundation -[NSURLConnectionInternalConnection invokeForDelegate:] 10 0x72d5da0 SocketIO Retain 3 00:10.415.214 0 Foundation -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] 11 0x72d5da0 SocketIO Release 2 00:10.415.216 0 Foundation -[NSURLConnectionInternalConnection invokeForDelegate:] 12 0x72d5da0 SocketIO Release 1 00:10.415.275 0 Foundation -[NSURLConnectionInternalConnection invokeForDelegate:] 13 0x72d5da0 SocketIO Retain 2 00:10.969.432 0 GraphicsServices GSEventRunModal 14 0x72d5da0 SocketIO Release 1 00:10.969.433 0 GraphicsServices GSEventRunModal 15 0x72d5da0 SocketIO Retain 2 00:10.969.434 0 GraphicsServices GSEventRunModal 16 0x72d5da0 SocketIO Release 1 00:10.969.456 0 GraphicsServices GSEventRunModal 17 0x72d5da0 SocketIO Retain 2 00:10.969.459 0 GraphicsServices GSEventRunModal 18 0x72d5da0 SocketIO Retain 3 00:10.969.488 0 Foundation -[NSCFTimer initWithFireDate:interval:target:selector:userInfo:repeats:] 19 0x72d5da0 SocketIO Release 2 00:10.976.115 0 MyProject -[SocketIO setTimeout] 20 0x72d5da0 SocketIO Retain 3 00:10.976.125 0 Foundation -[NSCFTimer initWithFireDate:interval:target:selector:userInfo:repeats:] 21 0x72d5da0 SocketIO Release 2 00:10.976.161 0 GraphicsServices GSEventRunModal 22 0x72d5da0 SocketIO Retain 3 00:13.935.328 0 GraphicsServices GSEventRunModal 23 0x72d5da0 SocketIO Release 2 00:13.935.373 0 MyProject -[SocketIO setTimeout] 24 0x72d5da0 SocketIO Retain 3 00:13.935.399 0 Foundation -[NSCFTimer initWithFireDate:interval:target:selector:userInfo:repeats:] 25 0x72d5da0 SocketIO Release 2 00:13.935.685 0 MyProject -[SocketIO onDisconnect] 26 0x72d5da0 SocketIO Release 1 00:13.935.705 0 MyProject -[MyViewController socketIODidDisconnect:] 27 0x72d5da0 SocketIO Release 0 00:13.935.716 0 GraphicsServices GSEventRunModal 28 0x72d5da0 SocketIO Zombie -1 00:13.936.298 0 GraphicsServices GSEventRunModal 
+6
source share
6 answers

To answer your question:

If you use an ARC-managed object from code other than ARC, you use it the same way you would if you used a non-ARC object: if you create or save it, you must free or auto-update it.

Regarding your problem:

In your comments, you mentioned that you tried to fix the initialization problem as follows

 self.chatSockIO = [[[SocketIO alloc] initWithDelegate:self] autorelease]; 

and in socketIODidDisconnect

 self.chatSockIO = nil; 

This should work fine if the chatSockIO property has retain semantics and that only one SocketIO object is used at a SocketIO .

Zombie's output gives a hint about what is going wrong:

  • In the second or last line, you release the object, the number of deductions drops to 0, and the object is freed. This is what you expect.
  • On the last line, however, it tries to save the object from the run loop. You know that this persists due to the exception that you get without NSZombie .
  • This means that although you did this with the object, it still gets calls from somewhere. This was unexpected.

It may be something in your code or an error in one of the libraries that you use. Just a hunch: In SocketIO.m replace these lines with -onDisconnect

 if (_webSocket != nil) { [_webSocket close]; } 

from

 if (_webSocket != nil) { [_webSocket close]; _webSocket.delegate = nil; } 
+3
source

This may not solve your problem, but in any case it is usually the idea of ​​TERRIBLE for releasing an object in a delegate call - it can get dealloc'd while continuing to work, and especially if the object is under ARC, it may not have the dealloc method.

So, convert your private delegate call to this:

 - (void) socketIODidDisconnect:(SocketIO *)socket { chatSockIO.delegate = nil; // don't want any more messages dispatch_async(dispatch_get_main_gueue(), ^{ self.chatSockIO = nil; }); // typed in text editor // your question - is the release needed? Well, under virtually every scenario yes, but I don't know this framework } 

If this fixes your problem or not, you should make the release this way - in the main thread AFTER the delegate returns. If you look at your code, you have to do EXACTLY with this ARC class, as with a regular class. The interaction is excellent, I have used several NON-ARC projects in my ARC application, while others have successfully done the opposite.

+1
source

In my experience, I would not mix ARC and non-ARC, expecting small small pieces of code. I spent a lot of time trying to find leaks and crashes.

If you cannot convert your program to ARC, consider using the non-ARC version of sockIO: https://github.com/pkyeck/socket.IO-objc/tree/non-arc

This will probably save you a lot of headaches.

0
source

I had similar problems. I solved this by setting @property(nonatomic, retain) over the class. In your case, it should be

in .h

  @property(nonatomic, retain) SockIO *socketIO; 

in .m

  @synthesize socketIO; chatSockIO = [[SocketIO alloc] initWithDelegate:self]; 

And you won’t be able to disrupt your application again!

0
source

ARC and non-ARC objects combine beautifully. Classes implemented using ARC can be used safely from code other than ARC. Whenever a ownership error occurs, the problem is probably in your code.

Without looking at the code, you cannot find the error, but it is probably a simple simple release.

Look at all the places in MyProject where the Release event is displayed on the tool track, for example -[SocketIO setTimeout] , -[SocketIO onDisconnect] and -[MyViewController socketIODidDisconnect:] . Check if there are incorrect ownership rights, for example, assignment to an instance variable processed by a save property or similar.

0
source

I am currently working on a project in which I did something similar, and the way I decided was to switch the project without ARC to ARC. Xcode passes everything for you, and all memory leaks and other problems have been resolved for me.

To upgrade to ARC, you need to:

1. Click "Edit-> Reactor-> Convert to Objective-C ARC

2. Select the targets and select the files you want to convert to ARC from the drop-down list

3. Click “Check” once you have selected the correct files.

4. Click "Next" and wait for the conversion to complete.

5. Click the Refresh button to refresh the code.

6. View your code

Hope this helps. It helps me

0
source

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


All Articles