NSNotificationCenter导致我的应用程序崩溃

4
我添加了一个NSNotificationCenter观察者,它会在两个不同的视图控制器上调用具有相同名称的2个选择器。
它可以工作,但当我运行应用程序时,有时会崩溃,并显示以下错误消息:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x18)

或者

Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

Image

有人知道为什么它会崩溃吗?谢谢!

.

我的代码:

fetchFromParse

-(void)sendAllStores
{
    [[NSNotificationCenter defaultCenter]postNotificationName:@"getStoresArrays" object:nil userInfo:self.storesDict];
}

firstVC.m:

- (void)viewDidLoad {
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(getStoresArrays:) name:@"getStoresArrays" object:nil];
}

-(void)getStoresArrays:(NSNotification*)notification
{
    NSLog(@“Working”);  
}

secondVC.m:

-(void)prepareArrays
{
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(getStoresArrays:) name:@"getStoresArrays" object:nil];
}
-(void)getStoresArrays:(NSNotification*)notification
{
    NSLog(@“Working”);
}

AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.secVC=[[secondVC alloc] init];
    [self.secVC prepareArrays];

    fetchFromParse *fetchFromParseObj=[[fetchFromParse alloc] init];
    [fetchFromParseObj getStoresFromParse];

    Return YES;
}

添加异常断点以获取更具体的信息。 - vadian
@vadian,它在其他地方总是崩溃,有时甚至不会崩溃。 - FS.O
在将self.storesDict作为通知的用户信息之前,您是否检查过它不是空的?self.secVC在应用程序委托中是否声明为strong属性? - John Rogers
@JohnRogers self.storesDict 不是 nil。而且,secVCfirstVC 都是强引用属性。 - FS.O
@FS.O 你找到这个崩溃的原因了吗? - Josh Wang
4个回答

3

通知崩溃

通常,如果您尝试在不删除观察器的情况下关闭视图控制器,则可能会看到这种崩溃。因此,Patil先生提供的答案部分是绝对必要的。您的用例将根据您删除观察器的位置和方式而有所不同。如果您过早地删除它,如果尝试引用任何相关对象,则可能会导致崩溃。

因此,您可能需要删除self.storesDict对象,或者至少在使用它之前验证它不为nil。

调试

这里有一个关于使用Xcode进行调试的快速教程。虽然是针对一个较旧版本的,但它应该可以让您迅速上手。您还可以查阅Apple 文档以获取有关收集崩溃日志的更多信息。

日志

您应该转到报告导航器并复制更多日志,以便我们可以确定问题的更精确原因。您可以在有错误的代码之前设置断点,然后逐步解决该问题。如果没有其他方法,请复制调试控制台。

获取崩溃日志

您可以打开Xcode,转到“窗口”菜单,选择“设备”。选择您连接的设备(iPhone / iPad),然后单击“查看设备日志”按钮。从列表中选择您的应用程序名称/崩溃日期。将数据复制到问题中。

更多信息

您提供的有关崩溃的信息越多,我们就越有可能帮助您。我怀疑答案是您正在尝试访问某个为nil的内容或者没有在正确的时间释放观察器。也许在视图消失时释放观察器不合适,但是您没有提供足够的信息来让这一点变得明显。

各个视图控制器如何协同工作?您确定通知引起了崩溃吗?在发布通知和每个选择器中都设置一个断点,然后调试应用程序,直到它崩溃。您需要确定导致崩溃的条件。如果您告诉我何时更新问题,我会改进此答案。


1

我会首先进行全局搜索,确保没有其他类正在监听该通知。然后我会确保在你添加了对该通知的观察者的类中执行以下操作:

-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

0

添加这个

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    //Has to be unregistered always, otherwise nav controllers down the line will call this method
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

希望对你有所帮助。


仍然崩溃,还有其他想法吗? - FS.O
你可以在 viewDidUnload 方法中尝试这个。 - Pradumna Patil
但是在iOS 6上,viewDidUnload已经被弃用了。 - FS.O
没问题,你仍然可以使用这个。 - Pradumna Patil
请查看此链接:https://dev59.com/x2035IYBdhLWcg3wBLTb。 - Pradumna Patil
显示剩余15条评论

0

你确定 'addObserver'、'postNotification' 和 'removeObserver' 总是在主线程上调用吗?

请再次确认:

if ([NSThread isMainThread])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接