Objective-C'de "tanınmayan seçici örneğe gönderildi" hatası


155

Bir düğme oluşturdum ve bunun için bir eylem ekledim, ancak çağrıldığı anda bu hatayı aldım:

-[NSCFDictionary numberButtonClick:]: unrecognized selector sent to instance
 0x3d03ac0 2010-03-16 22:23:58.811
 Money[8056:207] *** Terminating app
 due to uncaught exception
 'NSInvalidArgumentException', reason:'*** -[NSCFDictionary numberButtonClick:]:  unrecognized selector sent to instance 0x3d03ac0'

Bu benim kodum:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        UIButton *numberButton = [UIButton buttonWithType:UIButtonTypeCustom];        
        numberButton.frame = CGRectMake(10, 435, 46, 38);
        [numberButton setImage:[UIImage imageNamed:@"one.png"] forState:UIControlStateNormal];
        [numberButton addTarget:self action:@selector(numberButtonClick:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview: numberButton]; 
    }
return self;
}

-(IBAction)numberButtonClick:(id)sender{
    NSLog(@"---");
}

Yanıtlar:


187

Görünüşe göre görünüm denetleyicisini düzgün bir şekilde yönetmiyorsunuz ve bir noktada yeniden konumlandırılıyor - bu da numberButtonClicked:yöntemin şimdi görünüm denetleyicisinin daha önce işgal ettiği belleği işgal eden başka bir nesneye gönderilmesine neden oluyor ...

Görüntü denetleyicinizi doğru şekilde tuttuğunuzdan / serbest bıraktığınızdan emin olun.


105
Bu çok az kod satırından çok zeki bir teşhis.
Michael Morrison

41
Tamam, sorun tanımlandı ... ancak "Görünüm denetleyicinizi doğru şekilde tuttuğunuzdan / serbest bıraktığınızdan emin olun." bir çözüm değil, bir öneri.
Alex Gray

12
@alex grisi, Ne? Görünüm denetleyicisindeki doğru bellek yönetimi sorunu çözdü ... Bunun nasıl bir çözüm olmadığını anlamıyorum?
Jasarien

28
doğru. Bu "düzeltme" gibi görünse de .. ve ben azınlık olabilir, (ben hala var yönetmek rağmen), ama sorun ve çözüm arasındaki bağlantı hemen belli değil. Örneğin, karşılaşıyorum -[NSWindow end]: unrecognized selector sent to instance 0x100523e80 ve OP ile benzerlikleri ve hatta cevabınızdan sorunun nedenini fark etsem de, bir düzeltmenin uygulanması hemen belli değil
Alex Gray

12
Hemen belli oluyor. NSWindow bellek yönetiminiz hat boyunca bir yerde doğru değil. Yaşam döngüsünden geçin ve düzeltin.
Jasarien

127

Benim gibi Google ile buraya gelenler için, muhtemelen Xcode 4.2 + / iOS 5+ daha fazla, ARC ile ilgili. Aynı hatayla " tanınmayan seçici gönderiliyor " hatası aldım . Benim durumumda, bir UIButton'un gönderici parametresi olarak kendini geçmesi için ayarlanmış hedef eylemim vardı, ancak daha sonra buna ihtiyacım olmadığını fark ettim ve bunu kodda kaldırdım. Yani, şöyle bir şey:

- (IBAction)buttonPressed:(UIButton *)sender {

Olarak değiştirildi:

- (IBAction)buttonPressed {

Söz konusu UIButton'a sağ tıklandığında, İçeride Rötuş olayının görünüm denetleyicileri buttonPressed: yöntemiyle ilişkili olduğu görülmüştür. Bunu kaldırmak ve değiştirilmiş yönteme yeniden atamak bir tedavi olarak çalıştı.


Her ne kadar kendi soru ve yanıt bulmayı kolaylaştırır düşünüyorum, bu çok yararlı oldu.
Curtis Inderwiesche

@LeonardChallis Bir parametre olarak iletilmezse, buttonPressed'teki gönderene nasıl başvurabilirsiniz?
zakdances

8
Çok yardımcı yanıt. Ben sadece bu tam sorunla karşılaştım ve çözümünüz tam olarak doğru. Bu olduğunda iTunesU'daki Stanford iOS sınıfını takip ediyordum. Cevabınız için tekrar teşekkürler!
Marshall Alsup

1
@LeonardChallis Teşekkürler. Cevabınıza ücretsiz bir cevap ekledim.
1.21 gigawatts

1
Benzer bir sorunla mücadele ediyordum, gönderen parametresini seçici işlevden kaldırdım ve sonra göndereni nasıl alacağımı merak ettim. Benim durumumda, hatayı alıyordum çünkü seçici geri çağırma işleminden sonra iki nokta üst üste koymayı unuttum ve böylece bir çağrı sırası uyumsuzluğuna neden oldum. İki nokta üst üste işaretiyle gönderen argümanını koruyabilirim.

74

Bu, bu sorunun en iyi Google yanıtıydı, ancak farklı bir nedenim / sonucum vardı - başkalarının bu sorunla karşılaşması durumunda iki sentimi ekleyeceğimi düşündüm.

Ben de bu sabah benzer bir sorun yaşadım. Sorunu veren UI öğesini sağ tıklarsanız, hangi bağlantıların oluşturulduğunu görebilirsiniz. Benim durumumda iki eyleme kadar kablolanmış bir düğme vardı. İşlemleri sağ tıklama menüsünden sildim ve yeniden bağladım ve sorunum düzeltildi.

Bu nedenle, eylemlerin doğru bir şekilde bağlandığından emin olun.


Bu benim sorunumdu. Bir işlevi yeniden adlandırdım ve kodumu değiştirdim ancak xib dosyasındaki bağlantıyı değiştirmedim.
BFTrick

2
TEŞEKKÜR EDERİM! Sildiğim üç yöntem hala başvuruda bulundu. Bir hafta beni rahatsız ediyor!
erdekhayser

25

Tamam, buraya girmem gerek. OP , düğmeyi dinamik olarak oluşturdu . Benzer bir sorunum vardı ve cevap (avlanma saatlerinden sonra) o kadar basit ki beni hasta etti.

Kullanırken:

action:@selector(xxxButtonClick:)

or (as in my case)

action:NSSelectorFromString([[NSString alloc] initWithFormat:@"%@BtnTui:", name.lowercaseString])

Dizenin sonuna iki nokta üst üste koyarsanız, göndereni geçecektir. İki nokta üst üste dizenin sonuna yerleştirilmezse, alıcı bir tane beklerse hata alır. Etkinlik adını dinamik olarak oluşturuyorsanız iki nokta üst üste işaretini kaçırmak kolaydır.

Alıcı kodu seçenekleri şöyle görünür:

- (void)doneBtnTui:(id)sender {
  NSLog(@"Done Button - with sender");
}
 or
- (void)doneBtnTui {
  NSLog(@"Done Button - no sender");
}

Her zamanki gibi, kaçırılan her zaman açık cevaptır.


1
Çok teşekkür ederim! Bu benim sorunumdu (seçicinin adının sonuna iki nokta üst üste ':' koymamak). Neredeyse her zaman sabah saat 3'te kafalarımızı duvara vurduğumuz en aptal basit şeyler nasıl oluyor? Gerçekten teşekkür ederim!
TWright

23

Benim durumumda işlev bir bağımsız değişken beklemiyordu, ancak hataya neden olan düğme gönderilecek şekilde yapılandırıldı. Bunu düzeltmek için olay işleyiciyi yeniden sarmak zorunda kaldım.

İşte benim işlevi:

resim açıklamasını buraya girin

Bağımsız değişken içermediğine dikkat edin.

İşte düğme yapılandırmamın bir resmi (görüntülemek için düğmeye sağ tıklayın):

resim açıklamasını buraya girin

3 olay işleyicisi olduğuna dikkat edin.

Bunu düzeltmek için olay öğelerinden her birini kaldırmak zorunda kaldım, çünkü bunlardan biri enterPressed fonksiyonuna kendisine bir referans gönderiyor. Bu öğeleri kaldırmak için, hiçbir öğe görüntülenene kadar her bir öğenin adının yanındaki küçük x simgesini tıkladım.

resim açıklamasını buraya girin

Sonra düğmeyi etkinliğe yeniden bağlamak zorunda kaldım. Bunu yapmak için Kontrol tuşunu basılı tutun ve ardından düğmeden eyleme bir satır sürükleyin. "Bağlan Eylemi" yazmalıdır. Not: Bunun bir nedenle çalışması için XCode'u yeniden başlatmam gerekti; aksi takdirde yalnızca işlevin üstüne veya altına eylemler eklememe izin verir (diğer adıyla yeni bir eylem oluşturmak).

resim açıklamasını buraya girin

Artık hiçbir argüman iletmeyen button olayına bağlı tek bir olay işleyiciniz olmalıdır:

resim açıklamasını buraya girin

Bu cevap, @Leonard Challis tarafından da okunması gereken cevabı tamamlar.


14

Arabirim oluşturucuda görünümün "Sınıfını" ayarlamadıysanız da bu durum ortaya çıkabilir.


Agh teşekkür ederim! Bu, uygulamamın bir segue üzerinde çökmesine neden oluyordu, sadece kontrolörün sınıfını ayarlamayı unuttum.
Eichhörnchen

Neden sınıfı bilmek gerekiyor? Bir UIView olarak bir UITableViewSection kullanmaya çalışıyorum ve bu yüzden bu hatayı alıyorum. Derleyici UITableViewSection var olmadığını söylüyor, bu yüzden iç UIKit için varsayalım.
Ian Warburton

13

Benim durumumda NSNotificationCenter kullanıyordum ve hiçbir argüman almayan ancak iki nokta üst üste ekleyen bir seçici kullanmaya çalışıyordum. İki nokta üst üste işaretini kaldırmak sorunu çözdü.

Seçici adı kullanırken, bağımsız değişken yoksa bir sondaki iki noktayı kullanmayın. Bir argüman varsa, sondaki iki nokta üst üste kullanın. Birden fazla bağımsız değişken varsa, bunları her bağımsız değişken için sondaki iki nokta üst üste işaretiyle birlikte adlandırmalısınız.

Adam Rosenfield'ın cevabını buradan görebilirsiniz: Objective-C'deki seçiciler ?


11

Düğmeleri dinamik olarak oluşturduğum bir Swift projesinde bu sorunu yaşadım. Sorun kodu:

var trashBarButtonItem: UIBarButtonItem {
    return UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "newButtonClicked")
}

func newButtonClicked(barButtonItem: UIBarButtonItem) {
    NSLog("A bar button item on the default toolbar was clicked: \(barButtonItem).")
}

Çözüm, işlemden sonra tam bir kolon::: eklemekti: ör.

var trashBarButtonItem: UIBarButtonItem {
        return UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "newButtonClicked:")
    }

    func newButtonClicked(barButtonItem: UIBarButtonItem) {
        NSLog("A bar button item on the default toolbar was clicked: \(barButtonItem).")
    }

Tam örnek burada: https://developer.apple.com/library/content/samplecode/UICatalog/Listings/Swift_UIKitCatalog_DefaultToolbarViewController_swift.html


Öğreticiyi izledikten ve bu aynı konuda bir ipucu okuduktan hemen sonra
Düştüm

6

Bunun en açık nedeni (bütünlük için dahil edilmiştir) yanlış bir işaretçi yazmak ve yanlış sınıfın bir yöntemini çağırmaktır.

NSArray* array = [[NSArray alloc] init];
[(NSDictionary*)array objectForKey: key]; // array is not a dictionary, hence exception

Bu iyi bir ipucudur - bir görünümü veya veri nesnesini alt sınıflara ayırmamak (örneğin, alt sınıf adı ekleyememek), bunun gerçekleşmesinin başka bir yoludur
Brad M

4

Ben de aynı sorunu yaşadım.

Uibutton'umu film şeridimde sildim ve yeniden oluşturdum .. şimdi her şey iyi çalışıyor.


3

Benzer bir sorunum vardı, ama benim için çözüm biraz farklıydı. Benim durumumda, ben varolan sınıfını genişletmek için Kategori kullanılan (bazı boyutlandırma yetenekleri için UIImage - Bunu görmek howto durumda sen ilgilenen) ve yapı hedefe * .m dosyası eklemek unuttum. Aptalca bir hata, ama nereye baktığında her zaman belli değil. Paylaşmaya değer olduğunu düşündüm ...


3

Bu benim başıma oldu çünkü yanlışlıkla UIViewcontroller sınıf kodumdaki "@IBAction fonk ..." sildi, bu yüzden Storyboard'da Referans Çıkışı oluşturuldu, ancak çalışma zamanında bunu işlemek için herhangi bir işlev vardı.

Çözüm, özellik denetçisindeki Outlet referansını silmek ve daha sonra komut tuşuyla sınıf koduna sürükleyerek yeniden oluşturmaktı.

Umarım yardımcı olur!


Aynı şekilde, düğme artık var olmayan bir işleve başvurduğunda da bu benim başıma geldi.
Josh Wolff

2

Dönüş türünde IBAction yerine boşluğu kullanmanız gerektiğini düşünüyorum. çünkü programlı bir düğme tanımladınız.


2

Başka bir olası çözüm: Bağlayıcı argümanlarınıza '-ObjC' ekleyin.

Tam açıklama burada: Statik kütüphanedeki Objective-C kategorileri

Bence öz: kategori statik olarak bağlandığınız bir kütüphanede tanımlanmışsa, linker kategori yöntemlerinde bağlantı kuracak kadar akıllı değildir. Yukarıdaki bayrak, bağlayıcıyı, yalnızca kaynağınızı analiz etmeyi gerektirdiğini düşündüğü tüm nesnel C sınıflarında ve kategorilerinde yapar . (Lütfen bu cevabı ayarlamaktan veya düzeltmekten çekinmeyin. Bağlantılı dilleri biliyordum, bu yüzden burada papağan yapıyorum).


2

Aynı hatayla karşılaştım ve aşağıdakileri keşfettim:

Kodu kullandığınızda

[self.refreshControl addTarget:self action:@selector(yourRefreshMethod:) forControlEvents:UIControlEventValueChanged];

Seçiciyi aradığını düşünebilirsiniz:

- (void)yourRefreshMethod{
    (your code here)
}

Ama aslında seçiciyi arıyor:

- (void)yourRefreshMethod:(id)sender{
    (your code here)
}

Bu seçici mevcut değil, bu yüzden çökmeyi elde edersiniz.

Hatayı çözmek için seçiciyi (id) göndereni alacak şekilde değiştirebilirsiniz.

Ama ne yenileme işlevine çağrı diğer işlevleri varsa olmadan bir gönderene? Her ikisi için de çalışan bir işleve ihtiyacınız var. Kolay çözüm başka bir işlev eklemektir:

- (void)yourRefreshMethodWithSender:(id)sender{
    [self yourRefreshMethod];
}

Ve bunun yerine bu seçiciyi çağırmak için yenileme açılır kodunu değiştirin:

[self.refreshControl addTarget:self action:@selector(yourRefreshMethodWithSender:) forControlEvents:UIControlEventValueChanged];

Ayrıca Mac OSX'in en yeni sürümüne yükseltilemeyen eski bir Mac'te Stanford iOS kursunu yapıyorum. Bu yüzden hala iOS 6.1 için inşa ediyorum ve bu benim için sorunu çözdü.


2

Benim durumumda 2 saat sonra sorunu çözdüm:

Gönderenin (tabBar öğesi) herhangi bir Referans Çıkışı yoktu . Yani hiçbir yere işaret etmiyordu.

Juste işlevinize karşılık gelen bir referans çıkışı oluşturur .

Umarım bu size yardımcı olabilir.


Sadece eklemek için, benim durumumda IBActionSwift'e bir bağlantı noktasını unuttum . Bu nedenle, bu işlevi çağırmak istediğinden şikayet ediyordu, ancak bulunamadı.
DevNebulae

1

Şu anda iOS geliştirmeyi öğreniyorum ve aPress tarafından "iOS6 Geliştirme Başlıyor" kitabından geçiyorum. Aynı hatayı 10. Bölüm: Storyboard'larda alıyordum.

Anlamak iki gün sürdü, ancak yanlışlıkla TableView hücresinin etiketini olmamalı 1 olarak ayarladığımı öğrendim. Bu kitabı yapan ve benzer bir hata alan herkes için umarım bu yardımcı olur.

Gerçekten benim kod gelecek hataları bulmak daha kolay umut! hahaha. Hata ayıklama hatası onu anlamak için doğru yönde beni itmek için hiçbir şey yapmadı (ya da en azından hata ayıklayıcı, lol anlamak için çok yeni değilim).


1

Benim durumumda bir UIWebView kullanıyordum ve bir NSURL yerine ikinci parametrede bir NSString geçti. Bu nedenle, bir işleve iletilen yanlış sınıf türlerinin bu hataya neden olabileceğinden şüpheleniyorum.


1

..Ve şimdi benim

Düğmenin başka bir düğmenin parametresine erişen bir yönteme bağlı olduğunu ve düğmenin kendisiyle bir şey yapmaya çalıştığımda harika çalıştı, ancak bir kilitlenme yaşadım. Derleme sırasında hiçbir hata görüntülenmedi .. Çözüm?

Düğmeyi dosyanın sahibine bağlayamadım. Eğer buradaki herhangi biri benim kadar aptalsa, bunu dene :)


1

Yine biraz farklı bir çözüm / dava.

Xamarin ve MvvmCross kullanıyorum ve UIButton'u bir ViewModel'e bağlamaya çalışıyordum. UIButton bir Outlet ve bir TouchUpInside kadar kablolu vardı.

Bağlarken sadece Çıkışı kullanıyorum:

set.Bind (somethingOutlet).For ("TouchUpInside").To(vm => vm.Something);

Tek yapmam gereken XCode'daki eylem (TouchUpInside) bağlantısını kaldırmaktı ve bu çözüldü.

PS Sanırım bu tüm önceki cevaplar ve özellikle @Chris Kaminski ile ilgili üssünde, ama umarım bu birine yardımcı olur ...

Şerefe.


1

Aynı sorunu yaşadım. Benim için sorun, bir düğmenin iki Eylem yöntemi olmasıydı. Yaptığım şey, düğmem için bir ilk eylem yöntemi oluşturmak ve daha sonra görünüm denetleyicisinde silmektir, ancak bağlantı denetçisindeki ana film şeridindeki bağlantıyı kesmeyi unuttum. İkinci bir eylem yöntemi eklediğimde, artık bir düğmenin hataya neden olan iki eylem yöntemi vardı.


1

Benim için, arayüzler arası bij ctrl-dragging'te oluşturulan artık bir bağlantıydı. Bozuk bağlantının adı hata günlüğündeydi

*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[NameOfYourApp.NameOfYourClass nameOfCorruptConnection:]:
unrecognized selector sent to instance 0x7f97a48bb000'

Bir düğmeye bağlı bir eylemim vardı. Outlet artık kodumda bulunmadığı için düğmeye basmak uygulamanın çökmesine neden oldu. Günlükte isim aramak beni film şeridinde ona yönlendirdi. Silindi ve kaza gitti!


0

"Cha206" kullanıcısı gibi Stanford iOS sınıfı C193P'yi de aldığım için Leonard Challis'e cevap veriyorum

"Yakalanmayan 'NSInvalidArgumentException' istisnası nedeniyle uygulamayı sonlandırma, nedeni:"

Sorun, hesap makinesinde iki kez bağlı "Enter" düğmesine sahip olduğum ve bir arkadaşım Storyboard'da düğmenin incelenmesinin sağ tıklandığında 2 girişin "İçeride Rötuş" niteliklerinde olduğunu gösterdiğine dikkat çekti. "Enter" düğmesine basın. "İçeride Rötuş Yap" "Gönderilmiş Olaylar" dan birini silmek sorunu çözdü.

Bu, sorunun istisnaya neden olan 2 gönderilen olay olarak tetiklendiğini (Ödev 1'deki Hesap Makinesi İzlenmesinde C193P video sınıfı için) gösterdi.


Bazı 3 giriş vardı nasıl. :)
1.21 gigawatts

0

ViewController'ı InterfaceBuilder'daki ViewControllerScene'e atamazsanız oluşabilir. Bu nedenle ViewController.m herhangi bir sahneye bağlı değildir.



0

Bunun bir başka gerçekten saçma nedeni, seçicinin arabirimde (.h) tanımlanmış olması ancak uygulamada (.m) (pe typo) tanımlanmamış olmasıdır


0

Listeye eklemek için başka bir neden / çözüm. Bunun nedeni iOS6.0 (ve / veya kötü programlama). Eski sürümlerde, parametre türleri eşleşirse seçici eşleşir, ancak iOS 6.0'da, parametrenin adının doğru olmadığı daha önce çalışan kodda çökmeler yaşadım.

Gibi bir şey yapıyordum

[objectName methodName:@"somestring" lat:latValue lng:lngValue];

ama tanımında (hem .h hem de .m)

(viod) methodName:(NSString *) latitude:(double)latitude longitude:(double)longitude;

Bu, iOS5'te iyi çalıştı, ancak 6'da değil, aynı yapı farklı cihazlara dağıtıldı.

Derleyicinin bunu bana neden söylemediğini anlamıyorum, sorun çözüldü.


0

Bu, özel bir ControllerB sınıfı içindeki bir ControllerA'dan genel mülke bir özellik ayarlamak istediğinizde ve henüz storyboardlardaki kimlik denetçisinin içinde "Custom Class" ayarlamamışsanız da olabilir.


0

Sorunum ve çözümüm farklıydı ve gelecekteki okuyucuların başlarını duvara çarpmaktan kurtarabilmeleri için buraya göndermem gerektiğini düşündüm.

Aynı UIVIewController için farklı xib tahsis edildi ve hatta her yerde aradıktan sonra nasıl düzeltmek için bulamadık. Sonra AppDelegate'i aradığım yere baktım initWithNibNameve kodu kopyalarken xib adını değiştirdim, ancak UIViewControllersınıfı değiştirmeyi unuttum . Dolayısıyla, çözümlerin hiçbiri sizin için uygun değilse, initWithNibNameyönteminizi kontrol edin .


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.