Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C Library - cannot form weak reference to instance of class

I'm currently working with the XMPP Library for Objective-C, and I'm using the "Desktop" example code.

It logs in fine; however, when I open a new chat, or someone sends me a message, it crashes.

This seems like where something goes wrong:

XMPPStream[11678:1b03] RECV: 
2012-06-05 15:03:59:379 XMPPStream[11678:1b03] RECV: 
2012-06-05 15:03:59:382 XMPPStream[11678:403] RosterController: xmppRosterDidChange:
2012-06-05 15:03:59:387 XMPPStream[11678:403] RosterController: xmppRosterDidChange:
2012-06-05 15:04:01:900 XMPPStream[11678:403] tableView:shouldEditTableColumn:"jid" row:0
2012-06-05 15:04:01:900 XMPPStream[11678:403] user: 
objc[11678]: cannot form weak reference to instance (0x7fcd4a498930) of class ChatController

and

objc[11998]: cannot form weak reference to instance (0x7f853bd17c70) of class ChatController
(lldb) 
(lldb)

What does "Cannot form weak reference to instance....of class ChatController" mean? Do you guys know how I can fix it? I used an older version of this code with Snow Leopard and it worked, Lion is screwing me up!

Thank you!

like image 856
objectiveccoder001 Avatar asked Jun 05 '12 21:06

objectiveccoder001


3 Answers

In my project (as a mistake) there was a weak reference to self in dealloc (it was a separate method, called to clear used resource). Using weak reference to one property of this object (that captured just a reference to the resource) solved the problem.

It is really strange to create weak reference to half-destroyed object in dealloc.

NEVER WRITE LIKE THIS:

- (void) dealloc
{
    [self freeUsedResource];
}

- (void) freeUsedResource
{
    __weak MyClass *weakSelf = self;
    dispatch_async(self.queue, ^{

        [weakSelf.usedResource freeUsedMemory];
    });
}
like image 60
Akhrameev Avatar answered Oct 18 '22 23:10

Akhrameev


Looking at Mike Ash's blog, I found an interesting paragraph:

ARC's implementation of zeroing weak references requires close coordination between the Objective-C reference counting system and the zeroing weak reference system. This means that any class which overrides retain and release can't be the target of a zeroing weak reference. While this is uncommon, some Cocoa classes, like NSWindow, suffer from this limitation. Fortunately, if you hit one of these cases, you will know it immediately, as your program will crash with a message like this:

objc[2478]: cannot form weak reference to instance (0x10360f000) of class NSWindow

If you really must make a weak reference to classes such as these, you can use the __unsafe_unretained qualifier in place of __weak.

Did you turn ARC on in your app? If you turn it off, do you get better results?

like image 22
Michael Dautermann Avatar answered Oct 19 '22 01:10

Michael Dautermann


remember that you need to comment two places.

@interface GCDMulticastDelegateNode : NSObject
{
//#if __has_feature(objc_arc_weak)
//__weak id delegate;
//#else
__unsafe_unretained id delegate;
//#endif

dispatch_queue_t delegateQueue;
 }

 - (id)initWithDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;

 //#if __has_feature(objc_arc_weak)
 //@property (/* atomic */ readwrite, weak) id delegate;
 //#else
 @property (/* atomic */ readwrite, unsafe_unretained) id delegate;
 //#endif

 @property (nonatomic, readonly) dispatch_queue_t delegateQueue;

 @end
like image 1
Henry Avatar answered Oct 19 '22 01:10

Henry