很抱歉对我的问题的错误解释。这是我更新的代码和步骤。我也更新了标题。
!!!编辑!!!
1) 我正在使用 CoreData 数据库在 ARC 项目中实现搜索。
2) Search 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)searchDisplayControllerDidEndSearchUISearchDisplayController *)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)refreshActionid)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
或者它在主要功能上失败并显示 SIGABART。
对我来说,似乎有些东西发布得不好,但我使用的是 ARC,所以我不会手动处理释放对象...
Best Answer-推荐答案 strong>
在尝试了各种选项后,我得出结论,在 NSNotificationCenter 事件上使用单例作为观察者不是线程安全的。在将观察者逻辑从单例移动到普通 Controller 之后,一切正常。我已经尝试了各种单例实现,这些实现应该是 ARC 的线程安全的,但它们都不是作为观察者工作的。
经过测试的单例实现:
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/
|