【问题标题】:Delegate in singleton won't work单例中的代表不起作用
【发布时间】:2011-11-21 23:02:25
【问题描述】:

我有一个从外部数据库 (PTDatabaseAccsesser) 下载数据的单例。 下载完所有数据后,单例应该调用一个委托,它是 UITableViewController 的子类。但是,我收到此错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'-[__NSCFType doneDownloadingData]: unrecognized selector sent to instance... 

这就是我将委托设置为 UITableViewController 的子类的方式:

- (void)viewDidLoad {

    [[PTDatabaseAccesser sharedInstance] setDelegate:self];
    NSLog(@"%@", [[PTDatabaseAccesser sharedInstance] delegate]);
}

NSLog 显示这里的一切都是正确的。

这是调用委托的 PTDatabaseAccsesser 中的代码:

NSLog(@"%@", [self delegate]);
[[self delegate] doneDownloadingData];

然而,这里的 NSLog 显示委托与上面的错误消息中的类型相同。

这就是我创建单例的方式:

static PTDatabaseAccesser *sharedInstance;

+ (PTDatabaseAccesser *)sharedInstance {

    @synchronized(self) {

        if (!sharedInstance) sharedInstance = [[PTDatabaseAccesser alloc] init];
    }

    return sharedInstance;
}

+ (id)alloc {

    @synchronized(self) {

        sharedInstance = [super alloc];
    }

    return sharedInstance;
}

我已通过在上述两种方法实现中使用断点来确保单例可以正常工作。

【问题讨论】:

  • 当您发送委托消息给委托对象时,您确定委托对象是活动的吗?为了安全起见,当您释放控制器时,您应该 nil 委托。这样你就可以防止消息发送到僵尸对象
  • UITableViewController 子类的 viewDidLoad 在发送委托消息之前被调用,如果这就是你的意思的话。
  • @user957032 不,他的意思是子类在设置委托和发送消息之间被释放。你的单例应该保留它的委托,或者子类应该在它被释放之前将委托属性设置为 nil。
  • @Lio 你是对的。非常感谢!
  • @ughoavgfhw 你是对的。非常感谢!

标签: objective-c delegates singleton


【解决方案1】:

+alloc 中的代码似乎没有必要,可能是错误的根源。据我所见,sharedInstance+alloc 中获取其初始值,这意味着您在-sharedInstance 中的 if 条件可能永远不会执行,并且您正在调用未初始化对象的方法。试试这个代码,它也恰好更有效。

static PTDatabaseAccesser *sharedInstance;

+ (void) initialize
{
   sharedInstance = [[PTDatabaseAccesser alloc] init];
}

+ (PTDatabaseAccesser *)sharedInstance 
{
    return sharedInstance;
}

【讨论】:

  • 我现在已经尝试过了,但没有成功:/感谢您提供的代码 - 从现在开始使用它!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-18
  • 1970-01-01
  • 2012-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-02
相关资源
最近更新 更多