通知侦听器导致崩溃

时间:2012-01-16 23:38:58

标签: iphone ios xcode ipad

我正在使用以下代码检测/侦听iPad何时更改设备方向。

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];   
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didRotate:)
                                                 name:@"UIDeviceOrientationDidChangeNotification" 
                                               object:nil];

当事情发生变化时,这会调用我的didRotate:方法。在我的didRotate:方法中,我使用UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];来确定方向是什么,并相应地应用我的代码。

然而,在现实生活测试中,我注意到如果iPad在一个人的手中,则每秒都会调用didRotate:听起来似乎是倾听iPad中的每一个小倾斜和移位,这显然在一个人的手中发生了很多(而不是在桌子上平放)。

关于如何解决此问题的任何想法?我可以更改我的代码以使用界面方向,但无论出于何种原因我都遇到了麻烦。谢谢。

* UPDATE :此侦听器是在我的UIImageView子类中创建的。屏幕上有十几个或更多。我在删除实例时添加了[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];到我的删除方法中。这有助于解释为什么didRotate会出现这么多(我的错误)。

然而,我已经缩小了崩溃:每当我删除这个子类的一个实例,并旋转我的iPad时,我崩溃了。有时我得到像[__NSArrayM didRotate]这样奇怪的消息:是无法识别的选择器(以及其他像UIPanVelocity这样的奇怪对象......)。在删除实例后,我的监听器是否仍在监听?

已修复:感谢您的帮助。我终于发现了什么是错的。我删除了实例而没有删除观察者并结束通知。将以下代码添加到我的实例删除方法中可以解决我的问题:

[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] removeObserver:self];

2 个答案:

答案 0 :(得分:2)

我猜你反复添加观察者并且从不删除它们。这意味着可以针对单个事件多次调用相同的入口点。这也意味着当“自我”对象消失时,你会崩溃。

答案 1 :(得分:1)

仅当设备从一个方向更改为另一个方向时才会发送通知 - 它不会被激发超过必要的次数。

UIDeviceOrientation的方向比UIInterfaceOrientation多2个。它有FaceUp和FaceDown。可能正是这些被触发,你对它们不感兴趣。

typedef enum {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait,
UIDeviceOrientationPortraitUpsideDown,
UIDeviceOrientationLandscapeLeft,
UIDeviceOrientationLandscapeRight,
UIDeviceOrientationFaceUp,
UIDeviceOrientationFaceDown
} UIDeviceOrientation;

也许您更愿意在当前屏幕上的视图控制器中监听UIInterfaceOrientation更改。

typedef enum {
UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
} UIInterfaceOrientation;

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration