2009-08-13 2 views
3

Исходя из фона Symbian, меня несколько беспокоит кажущееся отсутствие обработки ошибок в Cocoa. У какао есть много методов, которые, насколько я вижу, не имеют сообщений об ошибках и все же могут потерпеть неудачу.Могу ли я доверять API-интерфейсам Cocoa не терпеть неудачу, или мне нужно защищать все?

Например, почему NSMutableString appendString имеет тип возврата void и не генерирует исключений (по крайней мере, documentation не упоминает о каком-либо)? Конечно, если я добавлю достаточно длинную строку, теоретически у меня может закончиться нехватка памяти. Является ли это параноидальным для меня, чтобы проверить длину NSMutableString до и после добавления, чтобы проверить, что приложение работает?

+5

К сожалению, Бретон, ваш совет не выясняет ничего –

ответ

6

Мой тест на Mac OS X, и я думаю, вы говорите о платформе iPhone.

Дело в том, что я не вижу, как возвращение ошибки из метода appendString поможет, поскольку платформа находится в этой точке в таком состоянии, что она не может удовлетворить запросы malloc для вашего процесса.

Чтобы обойти эту проблему, вы, вероятно, можете malloc собственное адресное пространство и использовать эту управляемую память процесса как хранилище для своих строк. Я думаю, что CFString от Carbon (бесплатный платный до NSString) позволяет вам использовать свой собственный распределитель памяти.

#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) 
{ 
    NSAutoreleasePool * pool = [NSAutoreleasePool new]; 
    NSMutableString * m = [NSMutableString stringWithCapacity:100000]; 

    int i; 
    for(i=0;i<1000000;i++) 
     [m appendString:@"ABCDE..."]; //1400 characters long 
    [pool release]; 
} 



cd:tmp diciu$ ./a.out 
a.out(2216) malloc: *** mmap(size=1220067328) failed (error code=12) 
*** error: can't allocate region 
*** set a breakpoint in malloc_error_break to debug 
[..] 
2009-08-13 16:45:44.163 a.out[2216:10b] *** Terminating app due to uncaught exception  'NSMallocException', reason: 'Out of memory. We suggest restarting the application. If you  have an unsaved document, create a backup copy in Finder, then try to save.' 
2009-08-13 16:45:44.165 a.out[2216:10b] Stack: (
    2494541803, 
    2485014075, 
    2435399864, 
    2494157025, 
    2494172776, 
    2434276628 
) 
Trace/BPT trap 
+0

Спасибо, diciu, за то, что вы меня на правильном пути. По-видимому, исключение * есть * брошенный. Я напишу ответ. –

+0

К сожалению, для iPhone все не так просто. Я использовал @trap и @catch вокруг кода, подобного вашему, и в эмуляторе я поймал (устаревшее!) Исключение NSMallocException. К сожалению, при отладке устройства я получаю:

 Program received signal: “0”. warning: check_safe_call: could not restore current frame 

+0

Если ваше приложение действительно может столкнуться с проблемами памяти, вы должны самостоятельно управлять памятью. Затем вы можете вызвать материал, который записывается в память, только если есть место для этого. В реальной жизни я не думаю, что вам когда-либо нужно беспокоиться о том, что appendString терпит неудачу из-за исчерпания памяти. – diciu

2

Я изменил тестирование NSMutableString appendString кода diciu на неудачу быстрее и попытаться поймать какие-либо исключения. Вот раздел ядра:

 
    NSMutableString * m = [[NSMutableString alloc] initWithCapacity:1000]; 
    NSMutableString * n = [[NSMutableString alloc] initWithCapacity:1000]; 
    @try { 
     [m appendString:@"1234567890"]; 
     [n appendString:m]; 
     int i; 
     for(i=0;i<100;i++) { 
      [m appendString:n]; 
      [n appendString:m]; 
     } 
    } 
    @catch (id exception) { 
     NSLog(@"!!Exception"); 
    } 
// @catch (NSException *exception) { 
//  NSLog(@"!!Exception: %@", [exception name]); 
// } 
    @finally { 
     [m release]; 
     [n release]; 
     NSLog(@"Finally..."); 
    } 

Я тестировал на различных платформах:

Mac OS X 10.5.8 & Xcode 3.1.3 iPhone 3,0 Emulator: Исключение брошено (NSException, с именем NSMallocException). Это хорошая новость, но странно, поскольку NSMallocException предположительно устарел.

iPhone 3.0.1: приложение аварийно завершает работу.

Плохая новость заключается в том, что для iPhone кажется, что нет никакой возможности поймать эту ошибку.

Хорошей новостью является то, что нет никакого защитного программирования, поскольку все приложение взрывается в любом случае!

Надеюсь, у кого-то есть лучший ответ.

+0

Для чего стоит 10.5.8 i386 RAM 4Gb, код выше не зависает, он выдает исключение (из памяти). – diciu

+0

Thanks diciu; вы более терпеливы, чем я. Когда я тестировал, я не ждал достаточно долго, чтобы поймать исключение. Я исправлю свой текст выше. –

Смежные вопросы