Objective-C Библиотека - не может сформировать слабую ссылку на экземпляр класса

В настоящее время я работаю с библиотекой XMPP для Objective-C, и я использую код примера "Рабочий стол".

Он записывается в порядке; однако, когда я открываю новый чат, или кто-то посылает мне сообщение, он падает.

Это похоже на то, что что-то не так:

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

и

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

Что означает "Невозможно сформировать слабую ссылку на экземпляр... класса ChatController"? Вы, ребята, знаете, как я могу это исправить? Я использовал более старую версию этого кода со Snow Leopard, и это сработало, Лев меня надувает!

Спасибо!

Ответ 1

Посмотрев блог Майка Эша, я нашел интересный параграф:

Реализация ARC обнуления слабых ссылок требует координация между системой подсчета ссылок Objective-C и обнуление слабой системы отсчета. Это означает, что любой класс, который переопределения сохранения и освобождения не могут быть целью обнуления слабых Справка. Хотя это необычно, некоторые классы Cocoa, такие как NSWindow, страдают от этого ограничения. К счастью, если вы ударите один из этих случаев, вы будете знать это немедленно, так как ваша программа будет сообщение вроде этого:

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

Если вы действительно должны сделать слабую ссылку на такие классы, как вы, может использовать квалификатор __unsafe_unredteded вместо __weak.

Вы включили ARC в своем приложении? Если вы отключите его, вы получите лучшие результаты?

Ответ 2

В моем проекте (как ошибке) была слабая ссылка на self в dealloc (это был отдельный метод, призванный очистить использованный ресурс). Использование слабой ссылки на одно свойство этого объекта (которое захватило только ссылку на ресурс) решило проблему.

Очень странно создавать слабую ссылку на полуразрушенный объект в dealloc.

НИКОГДА НЕ ПЛАНИРУЙТЕ ЭТО:

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

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

        [weakSelf.usedResource freeUsedMemory];
    });
}

Ответ 3

помните, что вам нужно прокомментировать два места.

@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