10

(下部の更新を参照してください)

最近、iPhoneアプリがバックグラウンドから戻ったときに、奇妙でまれなクラッシュが発生し始めました。クラッシュログは、システムコールのみで構成されています。

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000138
Crashed Thread:  0

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib                 0x34c715b0 objc_msgSend + 16
1   CoreFoundation                  0x368b7034 _CFXNotificationPost + 1424
2   Foundation                      0x34379d8c -[NSNotificationCenter postNotificationName:object:userInfo:] + 68
3   UIKit                           0x37ddfec2 -[UIApplication _handleApplicationResumeEvent:] + 1290
4   UIKit                           0x37c37d5c -[UIApplication handleEvent:withNewEvent:] + 1288
5   UIKit                           0x37c376d0 -[UIApplication sendEvent:] + 68
6   UIKit                           0x37c3711e _UIApplicationHandleEvent + 6150
7   GraphicsServices                0x36dea5a0 _PurpleEventCallback + 588
8   CoreFoundation                  0x3693b680 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 12
9   CoreFoundation                  0x3693aee4 __CFRunLoopDoSources0 + 208
10  CoreFoundation                  0x36939cb2 __CFRunLoopRun + 642
11  CoreFoundation                  0x368aceb8 CFRunLoopRunSpecific + 352
12  CoreFoundation                  0x368acd44 CFRunLoopRunInMode + 100
13  GraphicsServices                0x36de92e6 GSEventRunModal + 70
14  UIKit                           0x37c8b2fc UIApplicationMain + 1116
15  [MyAppName]                     0x00083d60 main (main.m:20)
16  [MyAppName]                     0x00080304 start + 36

これは、ゾンビオブジェクトが呼び出されているように見えるUIApplicationWillEnterForegroundNotificationか(スタックトレースでUIApplicationDidBecomeActiveNotification推測し、クラッシュする時刻)、次のようになります。_handleApplicationResumeEvent

  1. 私のクラスはどれもに登録UIApplicationDidBecomeActiveNotificationせず、2、3のシングルトン(永遠に生き続ける)だけがUIApplicationWillEnterForegroundNotification;に登録します。
  2. いくつかの実験を行いましたが、投稿UIApplicationWillEnterForegroundNotificationはから[UIApplication _sendWillEnterForegroundCallbacks:]のものであり、クラッシュログには含まれていません。

私にとって、これはすべて、使用しているライブラリのバグ、またはシステムのバグを意味し、クラッシュはiOS 5.1.1(リリースビルド)、iOS 6.0(リリースビルド)、iOS 6.0(リリースビルド)で1回発生しました。デバッグビルド)。使用しているすべてのライブラリをスキャンし、のソースコードにアクセスできましたが、どちらにも登録されていませUIApplicationWillEnterForegroundNotificationUIApplicationDidBecomeActiveNotification。私がアクセスできない唯一のライブラリはTestFlightですが、クラッシュはTestFlightの1.0バージョンと1.1バージョンの両方で発生し、私はそのような問題なしにかなり長い間前者を使用しています。要約すると、なぜこのクラッシュが発生したのか、それが何から来たのかはわかりません。何か案は?

更新1

DarthMikeとmattの助けに感謝して、私はこの問題をもう少し深く調査しました。UIApplicationResumedNotification通知センターのコールバックとログスタックトレースを使用することにより、この正確なスタックは、バックグラウンドからの復帰の一部として通知が発生した場合にのみ発生することを発見しました。そして、何を推測しますか?それはいくつかの「プライベート」通知であり、対応するパブリック識別子がありません。それは持っておらずuserInfo、そのオブジェクトはUIApplication(これより前に投稿された他の多くの通知と同じように)です。明らかに私はそれを使用していませんし、ソースコードを持っているライブラリも使用していません。私はインターネットでそれについての合理的な言及さえ見つけることができません!また、デバッグ中にもクラッシュが発生したため、TestFlightが原因であるとは非常に疑わしく、デバッグモードでTestFlightを「離陸」しません。

を受信するためのスタックトレースは次のとおりUIApplicationResumedNotificationです。オフセットはすべて同じですが、一定のバイトオフセットがあります(ライブラリに応じて2または4-おそらくデバッグスタックトレースであり、リリースではないため):

0   [MyAppName]                         0x0016f509 NotificationsCallback + 72
1   CoreFoundation                      0x3598ce25 __CFNotificationCenterAddObserver_block_invoke_0 + 124
2   CoreFoundation                      0x35911037 _CFXNotificationPost + 1426
3   Foundation                          0x333d3d91 -[NSNotificationCenter postNotificationName:object:userInfo:] + 72
4   UIKit                               0x36e39ec7 -[UIApplication _handleApplicationResumeEvent:] + 1294
5   UIKit                               0x36c91d61 -[UIApplication handleEvent:withNewEvent:] + 1292
6   UIKit                               0x36c916d5 -[UIApplication sendEvent:] + 72
7   UIKit                               0x36c91123 _UIApplicationHandleEvent + 6154
8   GraphicsServices                    0x35e445a3 _PurpleEventCallback + 590
9   CoreFoundation                      0x35995683 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
10  CoreFoundation                      0x35994ee9 __CFRunLoopDoSources0 + 212
11  CoreFoundation                      0x35993cb7 __CFRunLoopRun + 646
12  CoreFoundation                      0x35906ebd CFRunLoopRunSpecific + 356
13  CoreFoundation                      0x35906d49 CFRunLoopRunInMode + 104
14  GraphicsServices                    0x35e432eb GSEventRunModal + 74
15  UIKit                               0x36ce5301 UIApplicationMain + 1120
16  [MyAppName]                         0x000aa603 main + 390
17  [MyAppName]                         0x000a41b0 start + 40

NotificationsCallbackは、今のところデバッグ用に追加した「オブザーバー」コールバックです。

要点を証明するためremoveObserver:に、オブジェクトの1つからの呼び出しを意図的に省略して、ゾンビ/例外を生成しました。元のクラッシュと同様に、スタックトレースが含まれ_CFXNotificationPost + 1426、その後にinがクラッシュしEXC_BAD_ACCESSましたobjc_msgSend + 16。つまり、これはUIApplicationResumedNotification、オブザーバーが割り当て解除される前に、誰かがオブザーバーを登録し、削除していないことを意味します。私はそのような通知に登録したことがないという事実に基づいて、このクラッシュは私のせいではないと推測できます。それでも問題は残っています-それでは誰ですか?とにかく、誰が実際にこの通知に登録するのだろうか...

更新2

新しいバージョンのアプリでこのバグに変更があるかどうかを確認するのをまだ待っていますが、これが原因で以前のバージョンで別のクラッシュが発生しました。に登録するものは何でも、そのUIApplicationResumedNotificationセレクター_applicationResuming:を指定することがわかります。しかし、それが役に立ったとは思えません。

4

5 に答える 5

6

IOS 6.0.1を実行しているデバイスからのクラッシュレポートで、まったく同じスタックトレースがありました。次のパターンでシミュレーターで問題を再現することができました。

  • アプリケーションをバックグラウンドに置く
  • シミュレータメニューからメモリ警告をシミュレートする
  • アプリケーションをフォアグラウンドに戻します

多くのデバッグを行った後、_applicationResuming:メッセージがUITextFieldに送信され、メモリ警告への応答としてリリースしていることがわかりました。同じパターンをIOS5.1でテストしましたが、クラッシュは発生しませんでした。何らかの理由で、IOS 6のUITextFieldはApplicationResumeEventに登録されます(常にではないかもしれませんが、キーボードが表示された後)。
私の回避策は、このオブジェクトをリリースする前にNSNotificationCenterから削除することでした。

[[NSNotificationCenter defaultCenter] removeObserver:self.placeFld];
self.placeFld = nil;
于 2012-11-15T15:23:55.867 に答える
3

私はちょうどこの問題に遭遇し、通知を削除することを含まない解決策を見つけました。私たちの場合、これを行っていた古いコードがありました:

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
  [searchBar resignFirstResponder];
  // other stuff
}

なぜこれがあったのかわかりませんが、今はなくなり、クラッシュもなくなりました。この場合、searchBarTextDidBeginEditingが呼び出されている間にファーストレスポンダーを辞任すると、検索バーのテキスト編集フィールドで通知が孤立し、このUISearchBarを所有するビューコントローラーの割り当てが解除され、バックグラウンド/フォアグラウンドが実行されるとすぐにクラッシュするようです。ダンス。

YMMV

于 2013-03-27T07:21:02.157 に答える
2

にブレークポイントを設定し-[NSNotificationCenter postNotificationName:object:userInfo:]ます。もう存在しないオブジェクトなどに通知を送信しようとしています。自分の通知または自分のオブジェクトを誤って管理している可能性があります。

まだ使用していない場合は、ARCへの切り替えを検討してください。

静的アナライザーを使用します。潜在的なメモリの問題を見つけることができます。

于 2012-09-26T19:34:38.117 に答える
1

多くのことが考えられますが、UIApplication通知を登録するコードをチェックインする方がよいと思います。どの通知がエラーをトリガーするかは本当にわかりません。

また、AppDelegateで強い参照を保持/保持しているオブジェクトはありますか?奇妙な保持サイクルが発生し、このクラッシュが発生する可能性があります。

XCodeの誤動作によるこのようなクラッシュは見たことがありません。

編集:ヘッダーファイルからすべての通知を貼り付けます。やり過ぎかもしれませんが、アプリの履歴書/バックグラウンドから送信される可能性があります

UIKIT_EXTERN NSString *const UIApplicationDidEnterBackgroundNotification       NS_AVAILABLE_IOS(4_0);
UIKIT_EXTERN NSString *const UIApplicationWillEnterForegroundNotification      NS_AVAILABLE_IOS(4_0);
UIKIT_EXTERN NSString *const UIApplicationDidFinishLaunchingNotification;
UIKIT_EXTERN NSString *const UIApplicationDidBecomeActiveNotification;
UIKIT_EXTERN NSString *const UIApplicationWillResignActiveNotification;
UIKIT_EXTERN NSString *const UIApplicationDidReceiveMemoryWarningNotification;
UIKIT_EXTERN NSString *const UIApplicationWillTerminateNotification;
UIKIT_EXTERN NSString *const UIApplicationSignificantTimeChangeNotification;
UIKIT_EXTERN NSString *const UIApplicationWillChangeStatusBarOrientationNotification; // userInfo contains NSNumber with new orientation
UIKIT_EXTERN NSString *const UIApplicationDidChangeStatusBarOrientationNotification;  // userInfo contains NSNumber with old orientation
UIKIT_EXTERN NSString *const UIApplicationStatusBarOrientationUserInfoKey;            // userInfo dictionary key for status bar orientation
UIKIT_EXTERN NSString *const UIApplicationWillChangeStatusBarFrameNotification;       // userInfo contains NSValue with new frame
UIKIT_EXTERN NSString *const UIApplicationDidChangeStatusBarFrameNotification;        // userInfo contains NSValue with old frame
UIKIT_EXTERN NSString *const UIApplicationStatusBarFrameUserInfoKey;                  // userInfo dictionary key for status bar frame
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsURLKey                NS_AVAILABLE_IOS(3_0); // userInfo contains NSURL with launch URL
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsSourceApplicationKey  NS_AVAILABLE_IOS(3_0); // userInfo contains NSString with launch app bundle ID
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsRemoteNotificationKey NS_AVAILABLE_IOS(3_0); // userInfo contains NSDictionary with payload
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsLocalNotificationKey  NS_AVAILABLE_IOS(4_0); // userInfo contains a UILocalNotification
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsAnnotationKey         NS_AVAILABLE_IOS(3_2); // userInfo contains object with annotation property list
UIKIT_EXTERN NSString *const UIApplicationProtectedDataWillBecomeUnavailable NS_AVAILABLE_IOS(4_0);
UIKIT_EXTERN NSString *const UIApplicationProtectedDataDidBecomeAvailable    NS_AVAILABLE_IOS(4_0);
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsLocationKey           NS_AVAILABLE_IOS(4_0); // app was launched in response to a CoreLocation event.
UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsNewsstandDownloadsKey NS_AVAILABLE_IOS(5_0); // userInfo contains an NSArray of NKAssetDownlo
于 2012-09-26T13:25:29.070 に答える
-1

奇妙なクラッシュをデバッグする前に、デッキをクリアするために私が行ういくつかのこと。

クリーンビルド(ローカルにキャッシュされたファイルを削除します)。

シミュレーター/デバイスからアプリを削除します(XIBがキャッシュされる場合があります)。

Xcodeを再起動します(Xcodeが現在の設定と同期していない場合、いくつかの奇妙なバグがあります)。

その後、再試行してください。

于 2012-09-26T12:14:29.587 に答える