Bir iOS uygulamasını kilitlemenin güvenilir bir yolu nedir?


136

Kullanıcı gerçek bir kullanıcının yanlışlıkla yapması muhtemel olmayan belirli bir eylem gerçekleştirdiğinde kasıtlı olarak çökmesini sağlayarak benim app çökme raporlarını sahada test etmek istiyorum.

Ancak derleme zamanında uyarı oluşturmayan uygulama kilitlenmesini sağlamanın iyi ve güvenilir bir yolu nedir?

Düzenleme: Bu soruya görünüşte çok açık cevaplar Kakao tarafından yakalanan ve böylece app çökmesine neden olmayan istisnalara neden olduğunu unutmayın.


WebKit discarded an uncaught exceptionŞimdiye kadar tüm bu fikirleri elde ediyorum ! Bu günlerde uygulama çökmesinin çok zor olduğunu kim bilebilirdi?
Nestor

Bunların hiçbirinin WebKit ile ilgisi olduğunu düşünmüyorum ...
BoltClock

23
Evet, iPad 1'de Safari'yi açın ve çok sayıda resim içeren bir sayfaya göz atın. Her zaman benim için çalışıyor. : /
Alan B

4
(void)0/0;,(void)*(char*)0;
Kevin

1
Burada tanımlanmamış davranışları teşvik eden bazı cevaplara dikkat edin . Bu aslında çok kötü bir tavsiye!
usr

Yanıtlar:


140

Objective-C'de kötü erişim sağlamak için C'yi doğrudan kullanın

strcpy(0, "bla");

Not: Bu, bildiğim herhangi bir sistemde çalışırken - C çalışma zamanının VEYA derleyicinin gelecekteki bir sürümünde, bu artık bir çökmeye yol açmayabilir. bkz Objective-C tanımsız davranış KQUEUE Is boş gösterici? )

(bunu yapmak için hızlıca objC'ye köprü kurmanız gerekir)


Bu en güvenilir yol IMHO
Michał Kreft

Ah evet, bu da WebKit discarded an uncaught exceptionsorunu çözüyor.
Nestor

hala bir yazım hatası vardı: D hayır @ "bla" ama "bla"
Daij-Djan

4
Görünüşe göre ( stackoverflow.com/questions/13651642/… ), bu tanımsız bir davranış ve aslında çok kötü bir cevap! Derleyici yasal olarak her iki ifadeyi de optimize edebilir ve hiçbir şey yapamaz. Bu yanıtı silmenizi öneririm. İnsanların bunu yapmasına yol açabilir.
usr

3
ios ve osx ve pencerelerde ve redhat her zaman verilen bağlamda çöktü, geçerli olduğunu söyleyebilirim. Bir feragatname ekleyeceğim
Daij-Djan

97

Şu anki favorim:

assert(! "crashing on purpose to test <insert your reason here>");

Bir klasik:

kill( getpid(), SIGABRT );

Ve bazı pr0n:

*(long*)0 = 0xB16B00B5;

Hepsi çökme raporlama aracım tarafından yakalanan çökmeleri oluşturur.


14
assert, yayın sürümlerinde çökmüyor, bu yüzden bu bir iddia
DarthMike

6
yapı ayarlarınıza bağlıdır; Ayrıca, soru test hakkında olduğunu düşünüyorum, test yapılarında
iddiaları

3
Birçok kişi (ben dahil) serbest bırakma yapılarında takdim eder. Bunları devre dışı bırakmak için bir neden yoktur.
Sulthan

5
@Sulthan: assert()bir hata ayıklama özelliğidir, sürüm yapılarında bu tür bir rüzgarı bırakmak çok az mantıklıdır. Bunun için birim testleri var.
MestreLion

18
IMHO assertbir hata ayıklama özelliği değildir. Başarısız bir iddia, imkansız olduğunu düşündüğünüz bir hatadır. Öngörülemeyen sonuçları olan bir programı çalıştırmaya devam etmekten ziyade bir sürüm derlemesini iptal etmek daha iyidir.
djromero

27

Hepimiz iOS için Clang kullandığımızdan, bu oldukça güvenilirdir:

__builtin_trap();

Bunun tam olarak bu amaç için tasarlandığı avantajı vardır, bu nedenle derleyici uyarıları veya hataları oluşturmamalıdır.



22

İyi bir eski yığın taşmasına ne dersiniz :)

- (void)stackOverflow
{
    [self stackOverflow];
}

16

En popüler olanı - tanınmayan seçici çökmesi:

NSObject *object = [[NSObject alloc] init];
[object performSelector:@selector(asfd)];

Bu sınıfta -asdf yönteminin uygulanmadığından emin olun haha

Veya bağlı istisnanın ötesinde dizin:

NSArray * array = [NSArray array];
[array objectAtIndex:5];

Ve tabi ki kill( getpid(), SIGABRT );


12

Swift'te kolayca ölümcül bir hata atabileceğinizi düşünüyorum:

func foo() {
    fatalError("crash!")
}

Aslında uygulamanın çökmesini sağlamak için bir şeyler ters giderse bu özelliği kullanmak için tasarlanmıştır.

Özel bir durumda if ifadesinden kaçınmak için de kullanabilirsiniz precondition. Bu benzeyen assert, (isterse) oldukça net böylece niyeti yapar ve olmayan olarak nihai sürümde kaldırıldı assert. Gibi kullanılır precondition(myBoolean, "This is a helpful error message for debugging.").


9

Ayrılmış bir nesneye mesaj gönderme


34
Bu aslında çok güvenilmez. Bellekleri yeniden kullanılmadığı sürece, yeniden ayrılmış nesnelere ileti gönderebilirsiniz. İnsanların tarihsel olarak çift serbest bırakma hatalarını ayıklamak için çok zor olmasının nedeni budur. Yalnızca bellek başka bir nesne tarafından geri alındığında, bir mesaj göndermenin istisnaya neden olması mümkündür.
Mike Weller

7
exit(0);

(mutlaka ... yazınız ... 30 karakter)


Upvotes için teşekkürler ama aslında bu uygulama sona erdirecek ve Springboard'a geri dönecek, ki bu da kendi başına faydalı olsa da OP'nin istediği şey değil, bu da açılmamış bir istisnayı tetikleyecek
Steve Rogers

6

Ayrıca bir istisna oluşturabilirsiniz:

[NSException raise:NSInternalInconsistencyException
            format:@"I want to test app crashes!."];

2
İstisnanın iyi bir yol olduğunu düşünmüyorum, istisna yakalamak yaygındır, böylece yanlışlıkla yakalayabilirsiniz. Sinyalleri yakalamak çok yaygın değildir, bu nedenle kötü erişim veya benzer şeyler daha güvenilir olacaktır. :)
Michał Kreft

3

10 parmak dokunuşunu tanıyan bir görünüme jest tanıyıcı ekleyin (10 parmak biraz kalabalık olabileceğinden iPhone için 5 parmak). GR'de, uygulamanızın kilitlenmesini sağlamak için daha önce belirtilen kesin yollardan birini yürüten bir yöntem bulunur. Çoğu kullanıcı uygulamanızda 10 parmak bırakmayacaktır, bu nedenle kazara kazaya neden olan genel kullanıcıdan güvende olursunuz.

Bununla birlikte, Testflight gibi bir şeyi kullanabilmeniz veya yalnızca kişisel cihazlara dağıtabilmeniz ve Apple'a göndermeden önce vahşi ortamda test edebilmeniz gerekir. Zorunlu bir kilitlenme olması, uygulamanızın Apple tarafından reddedilmesine neden olabilir.


Aşırı bir çoklu dokunuş yaptığımda Cocos2d uygulamam çöküyor ve çözülmemiş bir hata olarak aldım. Hiç GR'im yok, ancak Cocos2d'de çoklu dokunmayı etkinleştirdim. Açıkladığınız kilitlenmeyi yaşıyor muyum? Bunun beklenen / aranan davranış olduğunu mu söylüyorsunuz?
Fredrik Johansson

@Fredrik Açıkladığınız çökme olduğunu düşünmüyorum (IMO çökmeleri asla beklenmemelidir ve kişisel olarak bu konuda uygulamanıza bir tane koymak için iyi bir fikir olduğunu düşünmüyorum). Kilitlenmeyi simgelemeyi ve uygulamanın hangi kilitlenmeye neden olduğunu tam olarak öğrenmeyi deneyebilirsiniz. Cocos2d çerçevesi içinde 'aşırı çoklu dokunma' oluştuğunda çökmeye neden olan bir şey olabilir. Eğer durum buysa, o zaman en iyi bahsiniz Cocos2d adamlarına bir hata veriyor.
jhelzer

2

gibi bir şey deneyebilir

NSArray* crashingArray = [NSArray arrayWithCapacity:1];
[crashingArray release];

EXC_BAD_ACCESS üzerinde kilitlenmelidir (ikinci kez serbest bırakmanız gerekebilir, ancak normalde zaten böyle çökmelidir)


3
ARC etkin derleme olmaz.
vikingosegundo

eğer ouy ARC kullanırsanız bunu da yapabilirsiniz: NSArray * crashingArray = [NSArray arrayWithCapacity: 1]; [crashingArray objectAtIndex: 0]; Bu çöküyor olmalı
Saliom

1

İle gideceğim:int raise(int sig);

Daha fazla bilgi almak için >man raise


0

Süreci normal olarak öldürürdüm:

kill(getpid(), SIGKILL);

Eğer sinyal ile bir işleyici yüklerseniz, aynı zamanda çökme, açık dosyaları ve bu şeyler yazmak için bitirme ele alabilirsiniz.



0

kullanırım

[self doesNotRecognizeSelector:_cmd]; 

2
Bu kod, yalnızca kod olduğu için otomatik olarak düşük kalite olarak işaretleniyor. Bunun sorunu neden çözdüğünü açıklamak için biraz metin ekleyerek genişletmeyi düşünür müsünüz?
gung - Monica

0

RubyMotion ile çalışırken bunu kullanıyorum:

    n=Pointer.new ('c', 1)
    n[1000] ='h'

0

Bunu dene:

- (IBAction)Button:(id)sender
{
    NSArray *array = [NSArray new];
    NSLog(@"%@",[array objectAtIndex:8]);
}

-1

yanlış bir NSLogifade bunu yapar

NSLog(@"%@",1);
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.