Objektiv-c / kakaolara bir istisna atmaq

Objektiv-c / kakao istisna atmaq üçün ən yaxşı üsul nədir?

392
27 нояб. 27 noyabrda Steph Thirion tərəfindən təyin olundu 2008-11-27 20:18 '08 saat 20:18 'də 2008-11-27 20:18
@ 13 cavab

Aşağıdakı kimi [NSException raise:format:] istifadə edirəm:

 [NSException raise:@"Invalid foo value" format:@"foo of %d is invalid", foo]; 
502
27 нояб. cavab e.James 27 Noyabr. 2008-11-27 20:25 '08 at 8:25 pm 2008-11-27 20:25

Diqqətli bir söz buradadır. Objective-C-də, bir çox oxşar dillərdən fərqli olaraq, adətən normal fəaliyyət zamanı baş verə biləcək səhvlərlə ümumi hallar istisna edilməməlidir.

Apple'ın Obj-C 2.0 sənədləri aşağıdakıları bildirir: "Mühüm: İstisnalar Objective-C-də qaynaqlıdır. Ümumi axını nəzarət üçün istisnalar və ya səhvləri göstərmək üçün (məsələn, əlçatmaz bir fayl) istifadə etməməlisiniz."

border=0

Apple'ın konseptual istisna işləmə sənədləri eyni şeyi izah edir, ancaq bir çox sözlə izah edir: "Mühüm: proqramı və ya gözlənilməz runtime səhvlərindən istifadəni ehtiva etməlisiniz, məsələn, toplusu məhdudiyyətlərdən kənara çıxmaq, dəyişməz obyektləri dəyişməyə cəhd etmək, yanlış mesaj göndərmək və pəncərə serverinə qoşulma itkisinə səbəb ola bilər.Bu proqram səhvləri istisna olmaqla, bu tip səhvlərə diqqət yetirirsiniz. [.....] İstisnalar yerinə Kakao tətbiqlərində gözlənilən səhvləri bildirmək üçün səhv obyektlərin (NSError) və Kakao səhvlərinin çatdırılmasını istərdim.

Bunun səbəbləri qismən Objective-C proqramlaşdırma deyimlərindən (sadə hallarda və daha çox kompleks hallarda NSError sinifində əks olunan parametrlərdən istifadə etməklə) əksər hallarda istisnaların atılması və tutulmasının daha bahalıdır və nəhayət, (və ən əhəmiyyətlisi, perpaps) ki, Objective-C istisnaları C setjmp () və longjmp () funksiyaları ətrafında incə bir sarğıdır, əslində hərtərəfli yaddaş işlənməsini pozur, bu şərhə baxın.

249
28 нояб. Cavab 28 noyabr tarixində zərərlə verilir. 2008-11-28 02:32 '08 at 2:32 2008-11-28 02:32
 @throw([NSException exceptionWith…]) 
57
27 нояб. Peter Hosey tərəfindən verilmiş cavab 27 noyabr 2008-11-27 21:35 '08 saat 09:35 'da 2008-11-27 21:35

EJames cavabına şərh vermək üçün heç bir şərhim yoxdur, buna görə mənə mina qoymaq lazımdır. Java fonundan gələnlər üçün, Java istisna və RuntimeException arasında fərqləndiyini xatırlayırsınız. İstisna yoxlanılmış istisna və RuntimeException yoxlanılmır. Xüsusilə, Java, "normal səhv şərtləri" üçün istisnalar istisnaları və bir proqramçı səhvinə səbəb olan "runtime səhvləri" üçün istisna edilməmiş istisnalar istisna edilməsini təklif edir. Objective-C istisnaları istisnayı istifadə etdiyiniz eyni yerlərdə istifadə edilməkdədir, istisnayı hesablamır və səhv kodu və ya NSError dəyərləri üçün qaytarılmış dəyərlər təyin edilmiş istisnadan istifadə etdiyiniz yerlərdə üstünlük təşkil edir.

33
08 июля '09 в 17:24 2009-07-08 17:24 Cavab, Daniel Yankowsky'ye 08 iyul '09 saat 17: 24-da verilmişdir 2009-07-08 17:24

ObjC 2.0 istisnalarından ötəri, Objective-C artıq C setjmp () longjmp () üçün bir sarıcı deyil və C ++ istisna ilə uyğun, @try "pulsuz", istisna və istisna - istisna daha bahalı.

Hər halda, ifadələr (NSAssert və NSCAssert makro ailələri istifadə edərək) NSException-ə səbəb olur və onları Ries dövlətləri kimi istifadə etmək məqsədəuyğundur.

14
07 нояб. Cavab Psycho 07 noyabr tarixində verilir. 2009-11-07 00:39 '09 da 0:39 'da 2009-11-07 00:39

NSException'i genişləndirən öz siniflərinizlə istifadə etmək daha yaxşı olardı. Sonra tutmaq üçün eyni qeyddən istifadə edirsiniz:

 @try { ..... } @catch{ ... } @finally{ ... } 

Apple istisnaları atmaq və idarə etmək üçün necə izah edir: İstisnalar İstisnaları atmaq

14
28 нояб. Cavab 28 avqustda rustyshelf tərəfindən verilir 2008-11-28 01:23 '08 saat 01:23 2008-11-28 01:23

Burada Böyük Nerd Ranch Kılavuzu'ndan (4-ci nəşr) bu mövzuda necə öyrəndim:

 @throw [NSException exceptionWithName:@"Something is not right exception" reason:@"Can't perform this operation because of this or that" userInfo:nil]; 
6
12 мая '14 в 10:33 2014-05-12 10:33 cavab Yohannes tərəfindən 12 may '14' də saat 10:33 'də veriləcək 2014-05-12 10:33

Tutmaq cəhd blokunda bir istisna yaratmaq üçün iki üsuldan istifadə edə bilərsiniz.

 @throw[NSException exceptionWithName]; 

və ya ikinci üsuldur

 NSException e; [e raise]; 
6
23 янв. Cavab verilir Subbu 23 yanvar. 2013-01-23 14:04 '13 at 14:04 2013-01-23 14:04

İstisnalar deyil, inkarların mübadiləsi üçün NSError istifadə edin.

NSError haqqında tez nöqtələr:

  • NSError, C-tərzi səhv kodlarının (tamsayıların) kök səbəbini dəqiq müəyyən etməyə imkan verir və inşallah səhv işçinin bu səhvin üstələməsinə imkan verir. Siz asanlıqla NDError nümunələrində SQLite kimi C kitabxanalarından səhv kodları kopyalayabilirsiniz.

  • NSError həmçinin bir obyekt olmaq üstünlüyünə malikdir və sözün lüğət lüğət userInfo istifadə edərək daha ətraflı şəkildə səhv təsvir etmək üçün bir yol təqdim edir.

  • Amma ən yaxşı şəkildə NSError atılmayacaqdır, buna görə də səhv rəftarına daha çox proaktiv yanaşma təşviq edir, digər dillərdən fərqli olaraq, isti kartofu uzaqdan atır və zəng yığınını uzadır, o anda istifadəçiyə məlumat verə bilər hər hansı mənalı şəkildə işlənir (ən yüksək səviyyədə OO qorunmasına uyğundur).

Referans: Referans

6
19 апр. Jason Fuerstenberg'ə 19 apreldə cavab verin 2012-04-19 05:58 '12 at 5:58 2012-04-19 05:58

Hesab edirəm ki, bir proqramın normal axınına nəzarət etmək üçün İstisnalar istifadə etməyin. Lakin dəyər istənilən dəyərə uyğun olmadığında istisnalar atılmalıdır.

Məsələn, bir funksiya bir dəyər qəbul edərsə və bu dəyər heç nil olmasına icazə verilmirsə, istisnanı aradan qaldırmaq və sonra "ağıllı" bir şey etməyə çalışın.

Ries

3
22 июля '09 в 20:01 2009-07-22 20:01 Cavab R. van Twisk tərəfindən 22 İyul tarixində saat 20: 00-da verilir. 2009-07-22 20:01

Bir proqramlaşdırma səhvini tapmaq və tətbiqin dayandırılmasını istəməyiniz yalnız istisnalar atmaq lazımdır. Buna görə istisnaları istisna etmək üçün ən yaxşı yol NSAssert və NSParameterAssert makrolarını istifadə etmək və NS_BLOCK_ASSERTIONS müəyyən edilməməsini təmin etməkdir.

0
30 июня '14 в 12:01 2014-06-30 12:01 Cavab gnasher729 30 iyun 'da 12:01' də verilir 2014-06-30 12:01

Case üçün nümunə kodu: @throw ([NSException exceptionWithName: ...

 - (void)parseError:(NSError *)error completionBlock:(void (^)(NSString *error))completionBlock { NSString *resultString = [NSString new]; @try { NSData *errorData = [NSData dataWithData:error.userInfo[@"SomeKeyForData"]]; if(!errorData.bytes) { @throw([NSException exceptionWithName:@"<Set Yours exc. name: > Test Exc" reason:@"<Describe reason: > Doesn't contain data" userInfo:nil]); } NSDictionary *dictFromData = [NSJSONSerialization JSONObjectWithData:errorData options:NSJSONReadingAllowFragments error: resultString = dictFromData[@"someKey"]; ... } @catch (NSException *exception) {  NSLog( @"Caught Exception Name: %@", exception.name);  NSLog( @"Caught Exception Reason: %@", exception.reason ); resultString = exception.reason; } @finally { completionBlock(resultString); } 

}

İstifadə edin:

 [self parseError:error completionBlock:^(NSString *error) { NSLog(@"%@", error); }]; 

Digər genişlənmiş vəziyyət:

 - (void)parseError:(NSError *)error completionBlock:(void (^)(NSString *error))completionBlock { NSString *resultString = [NSString new]; NSException* customNilException = [NSException exceptionWithName:@"NilException" reason:@"object is nil" userInfo:nil]; NSException* customNotNumberException = [NSException exceptionWithName:@"NotNumberException" reason:@"object is not a NSNumber" userInfo:nil]; @try { NSData *errorData = [NSData dataWithData:error.userInfo[@"SomeKeyForData"]]; if(!errorData.bytes) { @throw([NSException exceptionWithName:@"<Set Yours exc. name: > Test Exc" reason:@"<Describe reason: > Doesn't contain data" userInfo:nil]); } NSDictionary *dictFromData = [NSJSONSerialization JSONObjectWithData:errorData options:NSJSONReadingAllowFragments error: NSArray * array = dictFromData[@"someArrayKey"]; for (NSInteger i=0; i < array.count; i++) { id resultString = array[i]; if (![resultString isKindOfClass:NSNumber.class]) { [customNotNumberException raise]; // <====== HERE is just the same as: @throw customNotNumberException; break; } else if (!resultString){ @throw customNilException; // <====== break; } } } @catch (SomeCustomException * sce) { // most specific type // handle exception ce //... } @catch (CustomException * ce) { // most specific type // handle exception ce //... } @catch (NSException *exception) { // less specific type // do whatever recovery is necessary at his level //... // rethrow the exception so it handled at a higher level @throw (SomeCustomException * customException); } @finally { // perform tasks necessary whether exception occurred or not } 

}

0
09 нояб. Aleksandr B. tərəfindən verilmiş cavab 09 Nov. 2017-11-09 14:32 '17 'da 14:32' də 2017-11-09 14:32

İstisnaları istifadə etmək üçün heç bir səbəb yoxdur, adətən, lens C, iş qaydalarına istisna etmək üçün. Apple onu narahat edən NSError istifadə edir deyə bilər. Obj C uzun müddət ətrafında olub və bir anda ALL C ++ sənədləri eyni şeyi deyir. İstisna atmaq və tutmaq nə qədər bahalı olmasının səbəbi istisna ömrünün son dərəcə qısa olduğunu və ... Normal axına xüsusi. Həyatımda heç kimin eşitmədiyini eşitməmişəm ki, bu istisna atılmış və tutulmaq üçün uzun müddətdir.

Bundan əlavə, C-nin məqsədi çox bahalı olduğunu və C və ya C ++-da kod olduğunu düşünən insanlar var. Buna görə də, həmişə olduğu kimi, NSErrorun istifadəsi zəif məlumat və paranoyadır.

Lakin bu mövzu ilə bağlı sual hələ bir istisna atmanın ən yaxşı yolu olduğunu cavablandırmadı. NSError qayıtmaq yolları açıqdır.

Beləliklə: [NSException yüksəltmək: ... @ throw [[NSException alloc] initWithName .... və ya @ throw [[MyCustomException ...?

Burada qaydaları yuxarıda göstəriləndən fərqli olaraq bir az fərqli olaraq yoxlanılır / yoxlanılır.

Burada (java-metaforları istifadə edərək) arasında olan real fərq vacibdir → bir istisna olmaqla bərpa edə bilərəm. Və bərpa olsaydı, mən yalnız bir uğursuzluq demək deyil.

Bəzən bir neçə @catch Blokunda uğursuzluqların müəyyən tiplərini araşdıran bəzi tətbiq üsuluna sahib olacağımdan görə, mən istisnalar üçün @throw ilə xüsusi istisna dərsləri istifadə edirəm. Məsələn, mənim ərizəim ATM olsa, məndə "BlockingRequestExceedsBalanceException" üçün bir @catch bloku olacaq.

Mən NSException istifadə edirəm: istisnalar üçün, istisnalarımızı artırın, çünki istisnadan xilas olmaq üçün heç bir yolu yoxdur, onu daha yüksək səviyyədə tutmaq və onu qeydiyyatdan keçirmək istisna olmaqla. Bunun üçün xüsusi bir sinif yaratmaq mənası yoxdur.

Hər halda, mən bunu edirəm, ancaq bilmək istəyirəm ki, daha yaxşı, eyni dərəcədə ifadəli bir yol var. Öz kodumda uzun müddət əvvəl C hella kodunu dayandırdığımdan bəri API-lərdən birinə keçsəm də, heç vaxt NSError-ı qaytarmıram.

-7
29 окт. Cavab silindi_userə verildi 29 oktyabr 2010-10-29 02:07 '10 at 2:07 2010-10-29 02:07

digər suallar və ya bir sual