10

NSNotification kullanmanın altın kuralı-ed dealloc nedeniyle kilitlenmesine yol belirlemek içinnasıl NSNotification gözlemci

"ayırmanın observer (veya object) önce removeObserver çağrı" gibi görünüyor.

Bu kuralın takip edilmediği bir kod tabanı ile uğraşıyorum, ancak bu durumun yerini tespit edemiyorum. Ben koduyla aradı ve her addObserver eşleşen bir removeObserver olması garanti ama yine de aşağıdaki çeşitli kilitlenme raporlarını görüyorum ettik:

OS Version:  iPhone OS 5.0.1 (9A405) 
Report Version: 104 

Exception Type: SIGSEGV 
Exception Codes: SEGV_ACCERR at 0x8 
Crashed Thread: 0 

Thread 0 Crashed: 
0 libobjc.A.dylib      0x31516fbc objc_msgSend + 16 
1 Foundation       0x3195b50f __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_0 + 19 
2 CoreFoundation      0x37a02577 ___CFXNotificationPost_block_invoke_0 + 71 
3 CoreFoundation      0x3798e0cf _CFXNotificationPost + 1407 
4 Foundation       0x318cf3fb -[NSNotificationCenter postNotificationName:object:userInfo:] + 67 
5 UIKit        0x34e5ee25 -[UIApplication _handleApplicationSuspend:eventInfo:] + 697 
6 UIKit        0x34deed17 -[UIApplication handleEvent:withNewEvent:] + 2031 
7 UIKit        0x34dee3bf -[UIApplication sendEvent:] + 55 
8 UIKit        0x34dedd2d _UIApplicationHandleEvent + 5809 
9 GraphicsServices     0x3750bdf3 PurpleEventCallback + 883 
10 CoreFoundation      0x37a0a553 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 39 
11 CoreFoundation      0x37a0a4f5 __CFRunLoopDoSource1 + 141 
12 CoreFoundation      0x37a09343 __CFRunLoopRun + 1371 
13 CoreFoundation      0x3798c4dd CFRunLoopRunSpecific + 301 
14 CoreFoundation      0x3798c3a5 CFRunLoopRunInMode + 105 
15 GraphicsServices     0x3750afcd GSEventRunModal + 157 
16 UIKit        0x34e1c743 UIApplicationMain + 1091 
17 App         0x00002d2f main (main.m:14) 

bu çarpışma raporun Benim yorumum [UIApplication _handleApplicationSuspend:eventInfo:] için bir bildirim gönderme olmasıdır Bir gözlemci kaldırılmadan önce ayrılmıştı.

Bu yorumun doğru olduğu varsayılırsa, hangi bildirimin gönderilmekte olduğunun belirlenmesiyle ilgili nasıl giderim? Ve ideal olarak, ayrılan nesne türü nedir?

cevap

6

Sen -[NSNotificationCenter postNotificationName:object:userInfo:] sembolik kesme noktası ayarlamak ve kendisine geçirilen üçüncü argüman yazdırabilirsiniz (ilk olmanın NSNotificationCenter, ikinci _cmd) ayıklayıcı po komutunu kullanarak.

+0

harika bir fikir. 'Çalışma zamanı' noktasında postting postting 'noktasından yaklaşıyordum, ancak hata ayıklama sırasında iyi bir alternatif (ve asıl soruyu cevaplıyor). –

+3

Sadece biraz daha fazla ayrıntı eklemek için, önerildiği gibi '[NSNotificationCenter postNotificationName: object: userInfo:]' değerinde sembolik bir kesme noktası ekledim ve kesme noktasının "eylemi" ni "po $ r2" nin "debugger komutu" na ayarladım. Uygulamayı cihazda çalıştırıp askıya alırken, [UIApplication _handleApplicationSuspend: eventInfo:] 'sırasında gönderilen birçok bildirimi görüyorum, ancak kilitlenme raporu çağrı yığınıyla eşleşen tek bildirim" UIApplicationSuspendedNotification "ve" UIApplicationDidEnterBackgroundNotification "(tahmin edilebilir şekilde) –

+0

Harika yanıt. Daha önce kör olduğumu hissediyorum. Mac'te "debugger komutu" olarak "po $ rdi" kullanırsanız, Bildirim adını görebilirsiniz. – Charlesism

0

Bunu belirlemenin diğer bir yolu, ad parametresi değerini (bildirimi göndermek için ilettiğiniz dizge) elde etmektir ve bu dizgeyi/adı gözlemleyen herhangi bir nesnenin, nesnelerin yaşam döngüsünde veya oturumda gözlemlemeyi kaldırmak üzere ayarlandığını doğrulayın. ayrılıyor.