gpt4 book ai didi

ios - 发布通知后无法识别的选择器发送到实例并使用 ARC 单例接收

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:44:51 26 4
gpt4 key购买 nike

抱歉对我的问题的错误解释。这是我的代码和更新的步骤。我也更新了标题。
!!!编辑!!!

1) 我正在使用 CoreData 数据库在 ARC 项目中实现搜索。
2) 搜索 viewController 是从 mainStoryboard 中实例化的,如下所示:

搜索 Controller 在 Storyboard中,标识符为“搜索”

SearchTableViewController *searchController = (SearchTableViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:@"Search"];
[[[self tabBarController] parentViewController] presentViewController:searchController animated:NO completion:nil];

3) 呈现的带有搜索的 View Controller 在事件 controllerDidEndSearch 上关闭(例如,通过单击 UISearchBar 中的取消按钮)。

-(void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller
{
[self dismissViewControllerAnimated:NO completion:nil];
}

我的错误仅在我通过搜索打开和关闭 View Controller 时发生。

4) 有一个正在监听刷新事件的单例对象。

刷新服务.m

+(RefreshService *)getDefaultRefreshService {
if (DefaultRefreshService == nil) DefaultRefreshService = [[self allocWithZone:nil] init];
return DefaultRefreshService;
}
-(id)init {
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:NSSelectorFromString(@"refresh:") name:@"refresh_event" object:nil];
}
return self;
}

5)有一个刷新按钮,通过发布通知触发刷新

-(IBAction)refreshAction:(id)sender {
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"refresh_event" object:@"OK"]];
}

好的案例:
1. 启动应用。
2.点击刷新按钮
3. 一切正常,refreshService 收到通知并触发刷新方法 - 在第 4 点定义)

和失败的糟糕用例:
1. 启动应用。
2. 点击搜索按钮 - 见第 2 点
3. 点击取消 - 见第 3 点
4. 点击刷新按钮 - 见第 5 点)
5. 现在它在 refreshService 收到通知之前就失败了,相反我得到了错误:

-[NSAutoresizingMaskLayoutConstraint refresh:]: unrecognized selector sent to instance

-[__NSCFDictionary refresh:]: unrecognized selector sent to instance

或者在 main 函数上使用 SIGABART 失败。

对我来说,看起来有些东西发布不好,但我使用的是 ARC,所以我不处理手动释放对象...

最佳答案

在尝试了各种选项后,我得出结论,使用单例作为 NSNotificationCenter 事件的观察者不是线程安全的。将观察者逻辑从单例转移到普通 Controller 后,一切正常。我已经尝试过各种单例实现,这些实现应该是线程安全的,但没有一个作为观察者工作。

测试单例实现:

1)我的单例实现

+(RefreshService *)getDefaultRefreshService {
if (DefaultRefreshService == nil) DefaultRefreshService = [[self allocWithZone:nil] init];
return DefaultRefreshService;
}

2) 从这里开始实现 How do I implement an Objective-C singleton that is compatible with ARC?

+ (RefreshService *)getDefaultRefreshService
{
static RefreshService *DefaultRefreshService = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
DefaultRefreshService = [[self alloc] init];
});

return DefaultRefreshService;
}

3) 并从这里实现:What should my Objective-C singleton look like?

+ (void)initialize
{
static BOOL initialized = NO;
if(!initialized)
{
initialized = YES;
DefaultRefreshService = [[RefreshService alloc] init];
}
}

对于每三个选项,我都使用了这个 init() 方法:

-(id)init {
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:NSSelectorFromString(@"refresh:") name:@"refresh_event" object:nil];
}
return self;
}

关于ios - 发布通知后无法识别的选择器发送到实例并使用 ARC 单例接收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19860340/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com