๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿฅ– Bread Basics/Obj-c

Obj-C ๊ณต์‹ ๋ฌธ์„œ ์ •๋ฆฌ - ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

by BreadDev 2025. 4. 14.
728x90

์•ˆ๋…•ํ•˜์„ธ์š”. ์ด๋ฒˆ์—๋Š” Objective-C์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ(Exception Handling)์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ Objective-C ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ฐœ์š”

Objective-C ์–ธ์–ด๋Š” Java๋‚˜ C++๊ณผ ์œ ์‚ฌํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ตฌ๋ฌธ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ตฌ๋ฌธ์„ NSException, NSError ๋˜๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ํด๋ž˜์Šค์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์— ๊ฐ•๋ ฅํ•œ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์™ธ(Exception): ํ”„๋กœ๊ทธ๋žจ์˜ ์ •์ƒ์ ์ธ ์‹คํ–‰ ํ๋ฆ„์„ ์ค‘๋‹จ์‹œํ‚ค๋Š” ํŠน๋ณ„ํ•œ ์กฐ๊ฑด์œผ๋กœ, ๋‹ค์–‘ํ•œ ์˜ค๋ฅ˜ ์ƒํ™ฉ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ ํ™œ์„ฑํ™”ํ•˜๊ธฐ

Objective-C์—์„œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด GNU ์ปดํŒŒ์ผ๋Ÿฌ ์ปฌ๋ ‰์…˜(GCC) ๋ฒ„์ „ 3.3 ์ด์ƒ์—์„œ -fobjc-exceptions ์Šค์œ„์น˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ : ์ด ์Šค์œ„์น˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ OS X v10.3 ์ด์ƒ์—์„œ๋งŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „ ๋ฒ„์ „์—์„œ๋Š” ์˜ˆ์™ธ ์ฒ˜๋ฆฌ์™€ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•œ ๋Ÿฐํƒ€์ž„ ์ง€์›์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๐Ÿ“Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ธฐ๋ณธ ๊ตฌ์กฐ

์˜ˆ์™ธ๋Š” ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์˜ ์ •์ƒ์ ์ธ ํ๋ฆ„์„ ์ค‘๋‹จ์‹œํ‚ค๋Š” ํŠน๋ณ„ํ•œ ์กฐ๊ฑด์ž…๋‹ˆ๋‹ค. ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”(์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ๋˜์ ธ์ง„๋‹ค๊ณ  ํ‘œํ˜„) ์ด์œ ๋Š” ๋‹ค์–‘ํ•ฉ๋‹ˆ๋‹ค:

  • 0์œผ๋กœ ๋‚˜๋ˆ„๊ธฐ์™€ ๊ฐ™์€ ์‚ฐ์ˆ  ์˜ค๋ฅ˜
  • ์–ธ๋”ํ”Œ๋กœ์šฐ๋‚˜ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ
  • ์ •์˜๋˜์ง€ ์•Š์€ ๋ช…๋ น ํ˜ธ์ถœ(์˜ˆ: ๊ตฌํ˜„๋˜์ง€ ์•Š์€ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ)
  • ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ์ปฌ๋ ‰์…˜ ์š”์†Œ ์ ‘๊ทผ ์‹œ๋„

Objective-C ์˜ˆ์™ธ ์ง€์›์€ ๋„ค ๊ฐ€์ง€ ์ปดํŒŒ์ผ๋Ÿฌ ์ง€์‹œ์–ด๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค:

@try ๋ธ”๋ก

์ž ์žฌ์ ์œผ๋กœ ์˜ˆ์™ธ๋ฅผ ๋˜์งˆ ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋Š” @try{} ๋ธ”๋ก ์•ˆ์— ๋„ฃ์Šต๋‹ˆ๋‹ค.

@try {
    // ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ
}

@catch ๋ธ”๋ก

@catch{} ๋ธ”๋ก์€ @try{} ๋ธ”๋ก์—์„œ ๋˜์ ธ์ง„ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋กœ์ง์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ @catch{} ๋ธ”๋ก์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@catch (NSException *exception) {
    // ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ฝ”๋“œ
}

@throw ์ง€์‹œ์–ด

@throw ์ง€์‹œ์–ด๋Š” ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋˜์ ธ์ง€๋Š” ์˜ˆ์™ธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Objective-C ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ NSException ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ํ•„์ˆ˜๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

@throw exception;

@finally ๋ธ”๋ก

@finally{} ๋ธ”๋ก์€ ์˜ˆ์™ธ๊ฐ€ ๋˜์ ธ์ง€๋“  ๊ทธ๋ ‡์ง€ ์•Š๋“  ๋ฐ˜๋“œ์‹œ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

@finally {
    // ์ •๋ฆฌ ์ฝ”๋“œ
}

์˜ˆ์ œ ์ฝ”๋“œ

๋‹ค์Œ์€ ๊ฐ„๋‹จํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค:

Cup *cup = [[Cup alloc] init];
 
@try {
    [cup fill];
}
@catch (NSException *exception) {
    NSLog(@"main: Caught %@: %@", [exception name], [exception reason]);
}
@finally {
    [cup release];
}

NSException: Objective-C์—์„œ ์˜ˆ์™ธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ธฐ๋ณธ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

๐Ÿ“Œ ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•˜๊ธฐ

@try{} ๋ธ”๋ก์—์„œ ๋˜์ ธ์ง„ ์˜ˆ์™ธ๋ฅผ ์žก์œผ๋ ค๋ฉด @try{} ๋ธ”๋ก ๋‹ค์Œ์— ํ•˜๋‚˜ ์ด์ƒ์˜ @catch{} ๋ธ”๋ก์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. @catch{} ๋ธ”๋ก์€ ๊ฐ€์žฅ ๊ตฌ์ฒด์ ์ธ ๊ฒƒ๋ถ€ํ„ฐ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๊ฒƒ ์ˆœ์œผ๋กœ ์ •๋ ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋‹ค์Œ ์˜ˆ์ œ์™€ ๊ฐ™์ด ์˜ˆ์™ธ ๊ทธ๋ฃน๋ณ„๋กœ ์ฒ˜๋ฆฌ๋ฅผ ๋งž์ถคํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

@try {
    // ์ž ์žฌ์ ์œผ๋กœ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ์ฝ”๋“œ
}
@catch (CustomException *ce) {   // 1. ๊ฐ€์žฅ ๊ตฌ์ฒด์ ์ธ ์˜ˆ์™ธ ์œ ํ˜•์„ ์žก์Šต๋‹ˆ๋‹ค.
    // CustomException ์ฒ˜๋ฆฌ ์ฝ”๋“œ
}
@catch (NSException *ne) {       // 2. ๋” ์ผ๋ฐ˜์ ์ธ ์˜ˆ์™ธ ์œ ํ˜•์„ ์žก์Šต๋‹ˆ๋‹ค.
    // ์ด ์ˆ˜์ค€์—์„œ ํ•„์š”ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
}
@catch (id ue) {                 // ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์˜ˆ์™ธ - ๋ชจ๋“  ๊ฐ์ฒด
    // ๊ธฐํƒ€ ๋ชจ๋“  ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
}
@finally {                       // 3. ์˜ˆ์™ธ ๋ฐœ์ƒ ์—ฌ๋ถ€์™€ ๊ด€๊ณ„์—†์ด ํ•ญ์ƒ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    // ์ •๋ฆฌ ์ฝ”๋“œ
}

์˜ˆ์™ธ ๊ณ„์ธต(Exception Hierarchy): ๋” ๊ตฌ์ฒด์ ์ธ ์˜ˆ์™ธ๋ถ€ํ„ฐ ๋” ์ผ๋ฐ˜์ ์ธ ์˜ˆ์™ธ ์ˆœ์œผ๋กœ catch ๋ธ”๋ก์„ ๋ฐฐ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์˜ˆ์™ธ ๋˜์ง€๊ธฐ(Throwing Exceptions)

์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋ ค๋ฉด ์˜ˆ์™ธ ์ด๋ฆ„๊ณผ ๋˜์ ธ์ง„ ์ด์œ ์™€ ๊ฐ™์€ ์ ์ ˆํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

NSException *exception = [NSException exceptionWithName: @"HotTeaException"
                                                 reason: @"The tea is too hot"
                                               userInfo: nil];
@throw exception;

@catch{} ๋ธ”๋ก ๋‚ด์—์„œ ์ธ์ˆ˜๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๊ณ  @throw ์ง€์‹œ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์žกํžŒ ์˜ˆ์™ธ๋ฅผ ๋‹ค์‹œ ๋˜์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์ธ์ˆ˜๋ฅผ ์ƒ๋žตํ•˜๋ฉด ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@catch (NSException *exception) {
    // ์ผ๋ถ€ ์ฒ˜๋ฆฌ ์ˆ˜ํ–‰
    @throw; // ๋™์ผํ•œ ์˜ˆ์™ธ๋ฅผ ๋‹ค์‹œ ๋˜์ง‘๋‹ˆ๋‹ค
}

์˜ˆ์™ธ ๋‹ค์‹œ ๋˜์ง€๊ธฐ(Rethrowing): ์˜ˆ์™ธ๋ฅผ ๋ถ€๋ถ„์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•œ ํ›„ ํ˜ธ์ถœ ์Šคํƒ์˜ ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ ์ถ”๊ฐ€ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ๋‹ค์‹œ ๋˜์ง€๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค.

๐Ÿ“Œ ์˜ˆ์™ธ ์‚ฌ์šฉ ์‹œ ์ค‘์š”ํ•œ ๊ณ ๋ ค ์‚ฌํ•ญ

Objective-C์—์„œ ์˜ˆ์™ธ๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ผ๋ฐ˜์ ์ธ ํ๋ฆ„ ์ œ์–ด๋‚˜ ๋‹จ์ˆœํžˆ ์˜ค๋ฅ˜๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  ๋ฉ”์„œ๋“œ๋‚˜ ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Œ์„ ๋‚˜ํƒ€๋‚ด๊ณ , ์˜ค๋ฅ˜ ๊ฐ์ฒด์— ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

NSError: Objective-C์—์„œ ์˜ˆ์™ธ ๋Œ€์‹  ์˜ค๋ฅ˜ ์ƒํ™ฉ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ NSException ๊ฐ์ฒด๋งŒ ๋˜์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์–ด๋–ค Objective-C ๊ฐ์ฒด๋“  ์˜ˆ์™ธ ๊ฐ์ฒด๋กœ ๋˜์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. NSException ํด๋ž˜์Šค๋Š” ์˜ˆ์™ธ ์ฒ˜๋ฆฌ์— ๋„์›€์ด ๋˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ, ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์ง์ ‘ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ NSException์„ ์„œ๋ธŒํด๋ž˜์‹ฑํ•˜์—ฌ ํŒŒ์ผ ์‹œ์Šคํ…œ ์˜ˆ์™ธ๋‚˜ ํ†ต์‹  ์˜ˆ์™ธ์™€ ๊ฐ™์€ ํŠน์ˆ˜ํ•œ ์œ ํ˜•์˜ ์˜ˆ์™ธ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

// ์‚ฌ์šฉ์ž ์ •์˜ ์˜ˆ์™ธ ํด๋ž˜์Šค ์‚ฌ์šฉ ์˜ˆ
@try {
    if (![self connectToServer]) {
        NetworkException *exception = [[NetworkException alloc] 
                                       initWithName:@"ConnectionFailure"
                                       reason:@"์„œ๋ฒ„์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค"
                                       userInfo:nil];
        @throw exception;
    }
}
@catch (NetworkException *ne) {
    // ๋„คํŠธ์›Œํฌ ๊ด€๋ จ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
}

๋งˆ๋ฌด๋ฆฌ

Objective-C์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ ํ”„๋กœ๊ทธ๋žจ ์•ˆ์ •์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ์ค‘์š”ํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Objective-C์—์„œ๋Š” ์˜ˆ์™ธ๊ฐ€ ๋ฆฌ์†Œ์Šค๋ฅผ ๋งŽ์ด ์†Œ๋ชจํ•˜๋ฏ€๋กœ, ์ผ๋ฐ˜์ ์ธ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ์—๋Š” NSError๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์˜ˆ์™ธ๋Š” ์ •๋ง ์˜ˆ์™ธ์ ์ธ ์ƒํ™ฉ์—๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.