oc 中__weak id delegate在swift中使用的问题

This is an issue with GCDAsyncSocket and delegates inside Swift code (can apply to other delegate scenarios as well).

What you are experiencing here is:

  1. Swift creates a reference to self for the call of GCDAsyncSocket()
  2. Objective-C does something with it, but treats it as __weak basically not creating an additional reference Swift needs to care about.
  3. Swift finishes the call to GCDAsyncSocket() and ARC removes the reference to self as there is no other reference. Swift does not know that Objective-C still needs it.
  4. And as the delegate is declared as __weak it's gone in the Objective-C part as well.
  5. GCDAsyncSocket has no delegate anymore and complains about it.

Solutions:

  1. Add NSObject as a super class to your Swift class and then retain "self" inside your class to some global class variable inside your init(). Then ARC sees the reference and everything is fine. This will create a reference on the Swift side for the lifetime of the Object and __weak in Objective-C will work as intended.
  2. Or remove the __weak from GCDAsyncSocket and add a socket.Delegate(nil) in a Deinit() method of your Swift class. This will create a reference on the Objective-C side preventing ARC on the Swift side to dealloc it until you do it manually.

GCDAsyncSocket tries not to leak memory. In a pure Objective-C project this works fine as intended, but when using Objective-C from Swift you need to retain delegates on the Swift side if they are declares as __weak in Objective-C.

  • var socket is a result of your call to GCCDAsyncSocket. But self() is a parameter. The result of GCDAsyncSocket is retained but not the parameters used during the call as they are not referenced by anything before or during the call. In Swift every parameter is a reference, nothing is passed by value and that is the root cause of the problem. And without a strong reference the result from self() is gone once the invoked method finishes. In pure Objective-C it works as self is passed by value and not reference. – scythe42 Jul 23 '14 at 2:00


    With Xcode 6.1.1 I was able to resolve this issue by making my Swift class a subclass of NSObject (no need to do any retaining).

猜你喜欢

转载自blog.csdn.net/weixin_39872861/article/details/81589342