ViewController responsesToSelector: serbest bırakılan örneğe gönderilen mesaj (CRASH)


95

Tamam, anlaşma şu, hata ayıklama ve çökmelerim hakkında soru sormaktan nefret ediyorum . Genellikle kendim idare, ama sadece Çünkü edemez sonra bile bu yolumu olsun zaten birden fazla soru inceleyen .

Tamam, işte sorun şu, uygulamamı rastgele açıp kapayarak bu yığın izlemeyle çöküyor:

*** -[ViewController respondsToSelector:]: message sent to deallocated instance 0x1e5d2ef0

Nerede ViewControllerdeğişebilir, bazen kodumun çöktüğü yer bu özellikle HİÇBİR ilgiye ViewControllersahip değildir ve ona sahip değildir veya onu çağırmaz.

Ayrıca, bu konsol izini elde etmek için Zombies'i etkinleştirdim, aksi takdirde hiç konsol baskısı alamazdım, yalnızca şunu alırdım:, objc_msgSendbu, yayınlanan bir şeyle mesajlaştığım anlamına geliyor. Ama nerede olduğunu bulamıyorum ... Gerçekten sıkıştım! Genellikle çökmelerimde her zaman hata ayıklarım, bu yüzden gerçekten bu konuda takılı kaldım.

Yine, bu, farklı yerlerde, farklı zamanlarda, açılıp kapanmaktadır. Ve düştüğü yer ile neredeyse hiç alakası yokViewController . Ve bunu çok kafa karıştırıcı buluyorum.

Kodumdan herhangi birine ihtiyacınız var mı? Çok fazla dosyam var ve farklı yerlerde çöktüğü için kodumu dağıtmak karmakarışık olacak!

Şanssız sembolik kesme noktaları eklemeye çalıştım ve Zombies, iOS için Instruments uygulamasında kullanılamıyor. Desteksiz mimari çerçevelere sahip olduğu için uygulamamı simülatörde çalıştıramıyorum.

Herkese teşekkürler...


şu soruya
öz

Görüşlerinize geçiş şeklinizin tutarlı olduğunu varsayarsak, bize bir veya iki örnek gösterebilirsiniz. Standart push / presentViewController çağrıları yapıyorsanız iyi olmalısınız, ancak burada birçok insanın bir görünüm denetleyicisi tahsis etme / başlatma gibi şeyler yaptığını, ancak daha sonra bir itme / sunma yapmadığını, bunun yerine yalnızca denetleyicinin alt görünüm olarak görüntüleyin. Sadece rastgele bir örnek. Ancak bunu bir kod olmadan teşhis edemeyiz. Umarım birkaç parça neler olup bittiğini anlamamıza yardımcı olur, o yüzden bakalım.
Rob

Sembolik kesme noktalarını etkinleştirmeye ne dersiniz? Bunları eklemeyi deneyin: wiki.zemingo.com/index.php?title=Symbolic_Breakpoints
Stavash

@RobertRyan presentModalViewController kullanıyorum, alt görünüm olarak eklemiyorum
MCKapur

Benim durumumda, alt görünüm denetleyicim bir webView içeriyordu ve alt VC, webView'ın scrollView için temsilciydi. Delege referansını dealloc / viewWillDisappear sırasında manuel olarak kaldırmam gerekiyordu veya bu çökmeyi yaşadım. Umarım birine yardımcı olur.
Dermot

Yanıtlar:


169

Ayrılmış örnek hatalarını izlemek için Enstrümanlar'ı kullanın . Uygulamanızı profilleyin ( Cmd ⌘+ I) ve Zombies şablonunu seçin . Uygulamanız çalıştıktan sonra onu çökertmeyi deneyin. Böyle bir şey almalısın:

görüntü açıklamasını buraya girin

Ayrıldıktan sonra çağrılan nesneyi göstermek için açılır pencerede adresin yanındaki oka tıklayın.

görüntü açıklamasını buraya girin

Şimdi, değiştirilen her çağrının bu nesnenin sayısını koruduğunu görmelisiniz. Bunun nedeni, doğrudan alıkoyma / bırakma mesajları göndermenin yanı sıra otomatik serbest bırakma havuzlarının boşaltılması veya NSArrays'a eklenmesi olabilir.

RefCt sütunu, eylem çağrıldıktan sonra keepCount'u gösterir ve Sorumlu Arayan , gerçekleştirildiği sınıf adını ve yöntemi gösterir. Herhangi bir saklama / serbest bırakma üzerine çift tıkladığınızda, araçlar size bunun gerçekleştirildiği kod satırını gösterecektir (Bu çalışmıyorsa, aramayı, Genişletilmiş Ayrıntı bölmesinde ve karşılığını seçerek inceleyebilirsiniz ):

görüntü açıklamasını buraya girin

Bu , nesnenin tüm retCount yaşam döngüsünü incelemenizi sağlar ve muhtemelen sorununuzu hemen bulursunuz. Yapmanız gereken tek şey, en son sürüm için eksik muhafaza bulmak .


3
Sorun release, özellikle sonuncusu olmayabilir . Sorun herhangi bir dengesizliktir release. Ayrıca, retaindaha sonra işaret edeceğiniz ve daha sonra başvuracağınız bir şey için başarısız olabilirim .
Ken Thomases

1
Ayrıca, bir Zombi aletleri şablonum yok, bunun nedeni Xcode Beta 4.5 kullandığımdan olabilir, bu arada
4.4'e geçeceğim

2
Oh, Zombiler yalnızca iOS simülatöründe sağlanır.
İOS simülatöründe ÇALIŞAMIYORUM

Sadece küçük bir not. Bu, xcode 5'teki yeniliklerden. "Zombies enstrüman şablonu Xcode 5'te geliştirilmiştir ve artık cihazlarda kullanımı desteklemektedir. Cihazlarda Zombies kullanmak için iOS 7 gerekir." Bu not size yanımdan ve değerli zamanımın 2 saatini getirdi ...
nickfox

2
Bizim App eğer bu ne anlama gelir durur çökmesini ve bunun için bu cihazı kanca zaman hatası, bir "deallocated örneğine mesaj Gönderilen" vererek durur? (Sanki hastaya bir "tanısal test" verildiğinde "hastalık" ortadan kayboluyor.)
Praxiteles

59

benzer bir sorun vardı. Benim durumumda bir viewController'ın navigationController olaylarını alması gerekiyordu, bu yüzden gezinti denetleyicisi temsilcisi olarak kayıt oluyordu:

 self.navigationController.delegate = self;

Kilitlenme, bu denetleyici serbest bırakıldığında, ancak yine de görünüm denetleyicisinin temsilcisi olduğunda meydana gelir. Bu kodu dealloc'a eklemenin hiçbir etkisi olmadı:

-(void) dealloc
{
    if (self.navigationController.delegate == self)
    {
        self.navigationController.delegate = nil;
    }

çünkü dealloc çağrıldığı noktada, görünüm denetleyicisi görünüm hiyerarşisinden zaten çıkarılmıştır, bu nedenle self.navigationController sıfırdır, bu nedenle karşılaştırmanın başarısız olacağı garanti edilir! :-(

Çözüm, VC'yi gerçekten yapmadan hemen önce görünüm hiyerarşisinden çıkarken tespit etmek için bu kodu eklemekti. Görünümün ne zaman açılacağını ve itilmeyeceğini belirlemek için iOS 5'te tanıtılan bir yöntemi kullanır.

-(void) viewWillDisappear:(BOOL) animated
{  
   [super viewWillDisappear:animated];
   if ([self isMovingFromParentViewController])
   {
      if (self.navigationController.delegate == self)
      {
           self.navigationController.delegate = nil;
      }
   }
}

Artık çarpışma yok!


Ben de teşekkürler - bu yazıyı bulmak için sadece 4 saatlik arama gerekli.
daidai

Gönderdiğiniz için teşekkürler, aynı sorunu
yaşadım

Sizler böylesine rahatsız edici sorunlara nasıl çözüm buluyorsunuz? Şapkalar çıkar !!
ViruMax

4

Çözemeyenler için işte bazı diğer teknikler:

https://stackoverflow.com/a/12264647/539149

https://stackoverflow.com/a/5698635/539149

https://stackoverflow.com/a/9359792/539149

https://stackoverflow.com/a/15270549/539149

https://stackoverflow.com/a/12098735/539149

Araçları Xcode 5'te proje açılır penceresini -> Şemayı Düzenle ... Profil -> Enstrüman'ı tıklayıp Tahsisler veya Sızıntılar'ı seçip ardından uygulamanızın profilini çıkararak, ardından Aletleri durdurarak, Tahsisler ve "NSZombie Algılamayı Etkinleştir" öğelerinde bilgi düğmesini tıklayarak çalıştırabilirsiniz. .

Ancak, doğrudan com.apple.main-thread'den gelen mesajlar için bu muhtemelen hiçbir şey ortaya çıkarmayacaktır.

İki saatten fazla bir süre kafamı bu konuya çarptım ve cevabın, suçluyu bulana kadar kaba kuvvetle projemin bir kopyasını yorumlayarak keşfettiğim aşırı bir serbest bırakma olduğu ortaya çıktı:

[viewController release];
viewController = NULL;

Sorun, sürümün değişkeni NULL olarak ayarlamamasıdır.

Bu, onu NULL olarak ayarlamak, yeniden serbest bırakma çağrıları anlamına gelir, refcount azaltılır ve bellek, viewController'a başvuran değişkenler onunla bitene kadar hemen serbest bırakılır.

Yani ya ARC'yi etkinleştirin ya da projenizin sürekli olarak release veya NULL kullandığından emin olun, ancak ikisini birden kullanmayın. Tercihim NULL kullanmaktır çünkü o zaman bir zombiye gönderme şansı yoktur, ancak nesnelerin nerede serbest bırakıldığını bulmayı zorlaştırır.


4

Dün iOS'ta da aynı problemle karşılaşmıştım. Uygulama "Hakkında" alt görünümünde IAP yaptım ve "Hakkında" viewDidLoad'a İşlem Gözlemcisi ekledim. İlk kez satın aldığımda sorun yok, ancak ana pencereye dönüp tekrar satın almak için alt görünüme girdikten sonra, "ayrılmamış örneğe gönderilen mesaj" sorunu oluştu ve Uygulama çöktü.

- (void)viewDidLoad
{
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];                                           object:nil];
}

Transaction Observer'ı dealloc'ta kaldırdıktan sonra sorun çözüldü.

- (void)dealloc
{
    // Even though we are using ARC, we still need to manually stop observing any
    // NSNotificationCenter notifications.  Otherwise we could get "zombie" crashes when
    // NSNotificationCenter tries to notify us after our -dealloc finished.

    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

Çalışma zamanı zombieçöküşümü düzeltti ... inApp satın alımları için nesne alıyordum. Saatlerce kazdıktan sonra bunu buldum .... BÜYÜK TEŞEKKÜRLER Adam.
Mahendra

4

Çok benzer bir sorun yaşadım ve bunun, gezinme denetleyicisi delegeleri setinden kaynaklandığını anladım.

Aşağıdaki sorunumu çözdü,

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

    if (self.navigationController.delegate != self) {
        self.navigationController.delegate = self;
    }
}

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

    if (self.navigationController.delegate == self) {
        self.navigationController.delegate = nil;
    }
}

Teşekkürler!! burada da aynı sorundu.
pegpeg

2

OS X'te de aynı sorunu yaşadım.

- (void)dealloc@ SoftwareEvolved'in de söylediği gibi bunu çözmek için yeterli yöntem yok . Ancak maalesef - (void)viewWillDisappearyalnızca 10.10 ve sonraki sürümlerde mevcuttur.

NSViewController alt sınıfımda, zombi açısından tehlikeli tüm referansları nil olarak ayarladığım özel bir yöntem ekledim. Benim durumumda bu NSTableViewözellikler ( delegateve dataSource) idi.

- (void)shutdown
{
  self.tableView.delegate = nil;
  self.tableView.dataSource = nil;
}

Bu kadar. Süpervizyondan görünümü her kaldırmak üzereyken bu yöntemi çağırmanız gerekir.


2

Aynı Sorunu yaşadım. Hangi temsilcinin soruna neden olduğunu bulmak zordu, çünkü herhangi bir satır veya kod ifadesini göstermiyor. Bu yüzden bir şekilde denedim, Belki sana yardımcı olur.

  1. Xib dosyasını açın ve dosyanın sahibinden, sağ taraftaki "bağlantı denetçisini göster" menüsünü seçin. Delegeler listelenir, şüpheli olanları sıfıra ayarlayın.
  2. (Benim durumumla aynı) Textfield gibi Özellik Nesnesi sorun yaratabilir, Bu yüzden temsilcilerini nil olarak ayarlayın.
-(void) viewWillDisappear:(BOOL) animated{

[super viewWillDisappear:animated];

if ([self isMovingFromParentViewController]){

self.countryTextField.delegate = nil;

self.stateTextField.delegate = nil;

}

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.