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

Obj-C ๊ณต์‹ ๋ฌธ์„œ ์ •๋ฆฌ - ๋น ๋ฅธ ์—ด๊ฑฐ(Fast Enumeration)

by BreadDev 2025. 4. 14.
728x90

์•ˆ๋…•ํ•˜์„ธ์š”. ์ด๋ฒˆ์—๋Š” Objective-C์—์„œ ์ปฌ๋ ‰์…˜์˜ ์š”์†Œ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ๋Š” ๋น ๋ฅธ ์—ด๊ฑฐ(Fast Enumeration) ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. iOS/macOS ๊ฐœ๋ฐœ์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์ด ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์„ ์ž์„ธํžˆ ์•Œ์•„๋ด…์‹œ๋‹ค.

๐Ÿ“Œ ๋น ๋ฅธ ์—ด๊ฑฐ๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

๋น ๋ฅธ ์—ด๊ฑฐ๋Š” ์ปฌ๋ ‰์…˜์˜ ๋‚ด์šฉ์„ ํšจ์œจ์ ์ด๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ์—ด๊ฑฐํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” Objective-C์˜ ์–ธ์–ด ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ๊ฐ„๊ฒฐํ•œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐ์—ด, ๋”•์…”๋„ˆ๋ฆฌ, ์„ธํŠธ ๋“ฑ์˜ ์ปฌ๋ ‰์…˜ ์š”์†Œ๋ฅผ ์‰ฝ๊ฒŒ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋น ๋ฅธ ์—ด๊ฑฐ(Fast Enumeration): Objective-C์—์„œ ์ปฌ๋ ‰์…˜์˜ ์š”์†Œ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ˆœํšŒํ•˜๊ธฐ ์œ„ํ•œ ์–ธ์–ด ๊ธฐ๋Šฅ์œผ๋กœ, for...in ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ for...in ๊ตฌ๋ฌธ

๋น ๋ฅธ ์—ด๊ฑฐ์˜ ๊ตฌ๋ฌธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋ฉ๋‹ˆ๋‹ค:

for (Type newVariable in expression) { statements }

๋˜๋Š” ๊ธฐ์กด ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ:

Type existingItem;
for (existingItem in expression) { statements }

๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘, expression์€ NSFastEnumeration ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ณต ๋ณ€์ˆ˜๋Š” ์ฐจ๋ก€๋กœ ๋ฐ˜ํ™˜๋œ ๊ฐ์ฒด์˜ ๊ฐ ํ•ญ๋ชฉ์œผ๋กœ ์„ค์ •๋˜๊ณ , statements๋กœ ์ •์˜๋œ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋ณต ๋ณ€์ˆ˜(Iterating Variable): ์—ด๊ฑฐ ๊ณผ์ •์—์„œ ๊ฐ ์š”์†Œ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค.
NSFastEnumeration: ๋น ๋ฅธ ์—ด๊ฑฐ๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ์ฒด๊ฐ€ ์ค€์ˆ˜ํ•ด์•ผ ํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค.

๋ฐ˜๋ณต ๋ณ€์ˆ˜๋Š” ์†Œ์Šค ๊ฐ์ฒด ํ’€์ด ์†Œ์ง„๋˜์–ด ๋ฃจํ”„๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ nil๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ๋ฃจํ”„๊ฐ€ ์ผ์ฐ ์ข…๋ฃŒ๋˜๋ฉด ๋ฐ˜๋ณต ๋ณ€์ˆ˜๋Š” ๋งˆ์ง€๋ง‰ ๋ฐ˜๋ณต ํ•ญ๋ชฉ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ƒํƒœ๋กœ ๋‚จ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ ๋น ๋ฅธ ์—ด๊ฑฐ์˜ ์žฅ์ 

๋น ๋ฅธ ์—ด๊ฑฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค:

  1. ํšจ์œจ์„ฑ: NSEnumerator๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์ƒ๋‹นํžˆ ๋” ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.
  2. ๊ฐ„๊ฒฐํ•œ ๊ตฌ๋ฌธ: ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•˜๊ณ  ์ฝ๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.
  3. ์•ˆ์ „์„ฑ: ์—ด๊ฑฐ์ž์—๋Š” ๋ณ€๊ฒฝ ๋ฐฉ์ง€ ๊ธฐ๋Šฅ์ด ์žˆ์–ด ์—ด๊ฑฐ ์ค‘์— ์ปฌ๋ ‰์…˜์„ ์ˆ˜์ •ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  4. ๋™์‹œ ์—ด๊ฑฐ ๊ฐ€๋Šฅ: ๋ฐ˜๋ณต ์ค‘ ๊ฐ์ฒด ๋ณ€๊ฒฝ์ด ๊ธˆ์ง€๋˜๋ฏ€๋กœ ์—ฌ๋Ÿฌ ์—ด๊ฑฐ๋ฅผ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ณ€๊ฒฝ ๋ฐฉ์ง€ ๊ธฐ๋Šฅ(Mutation Guard): ์—ด๊ฑฐ ์ค‘ ์ปฌ๋ ‰์…˜์ด ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ์•ˆ์ „ ์žฅ์น˜์ž…๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์ธก๋ฉด์—์„œ๋Š” ํ‘œ์ค€ for ๋ฃจํ”„์ฒ˜๋Ÿผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. break๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ˜๋ณต์„ ์ค‘๋‹จํ•˜๊ณ  continue๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ ์š”์†Œ๋กœ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ ๋น ๋ฅธ ์—ด๊ฑฐ ์ฑ„ํƒํ•˜๊ธฐ

๋‹ค๋ฅธ ๊ฐ์ฒด์˜ ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ œ๊ณตํ•˜๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ง„ ๋ชจ๋“  ํด๋ž˜์Šค๋Š” NSFastEnumeration ํ”„๋กœํ† ์ฝœ์„ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Foundation ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์ปฌ๋ ‰์…˜ ํด๋ž˜์Šค์ธ NSArray, NSDictionary, NSSet์€ ์ด ํ”„๋กœํ† ์ฝœ์„ ์ฑ„ํƒํ•˜๋ฉฐ, NSEnumerator๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

NSArray์™€ NSSet์˜ ๊ฒฝ์šฐ ์—ด๊ฑฐ๊ฐ€ ๊ทธ๋“ค์˜ ๋‚ด์šฉ์„ ๋Œ€์ƒ์œผ๋กœ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ฌธ์„œ์—์„œ ์–ด๋–ค ์†์„ฑ์ด ๋ฐ˜๋ณต๋˜๋Š”์ง€ ๋ช…ํ™•ํžˆ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

  • NSDictionary: ํ‚ค(key)๋ฅผ ์—ด๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
  • NSManagedObjectModel: ์—”ํ‹ฐํ‹ฐ(entity)๋ฅผ ์—ด๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

์ฑ„ํƒ(Adoption): ํด๋ž˜์Šค๊ฐ€ ํŠน์ • ํ”„๋กœํ† ์ฝœ์˜ ์š”๊ตฌ์‚ฌํ•ญ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ๋น ๋ฅธ ์—ด๊ฑฐ ์‚ฌ์šฉ ์˜ˆ์ œ

NSArray์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ

NSArray *array = [NSArray arrayWithObjects:
        @"one", @"two", @"three", @"four", nil];
 
for (NSString *element in array) {
    NSLog(@"element: %@", element);
}

์ด ์ฝ”๋“œ๋Š” ๋ฐฐ์—ด์˜ ๊ฐ ์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ฝ˜์†”์— ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

NSDictionary์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
    @"quattuor", @"four", @"quinque", @"five", @"sex", @"six", nil];
 
NSString *key;
for (key in dictionary) {
    NSLog(@"English: %@, Latin: %@", key, [dictionary objectForKey:key]);
}

์ด ์˜ˆ์ œ์—์„œ๋Š” ๋”•์…”๋„ˆ๋ฆฌ์˜ ๋ชจ๋“  ํ‚ค๋ฅผ ์ˆœํšŒํ•˜๊ณ , ๊ฐ ํ‚ค์™€ ํ•ด๋‹น ๊ฐ’์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

NSEnumerator์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ

NSArray *array = [NSArray arrayWithObjects:
        @"one", @"two", @"three", @"four", nil];
 
NSEnumerator *enumerator = [array reverseObjectEnumerator];
for (NSString *element in enumerator) {
    if ([element isEqualToString:@"three"]) {
        break;
    }
}
 
NSString *next = [enumerator nextObject];
// next = "two"

์ด ์˜ˆ์ œ๋Š” ๋ฐฐ์—ด์˜ ์—ญ๋ฐฉํ–ฅ ์—ด๊ฑฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , "three" ๋ฌธ์ž์—ด์„ ๋งŒ๋‚˜๋ฉด ๋ฃจํ”„๋ฅผ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ํ›„์—๋„ ์—ด๊ฑฐ์ž๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์ธ๋ฑ์Šค์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ

์ˆœ์„œ๊ฐ€ ์ž˜ ์ •์˜๋œ ์ปฌ๋ ‰์…˜(์˜ˆ: NSArray)์˜ ๊ฒฝ์šฐ, ์—ด๊ฑฐ๋Š” ํ•ด๋‹น ์ˆœ์„œ๋Œ€๋กœ ์ง„ํ–‰๋˜๋ฏ€๋กœ ๋ฐ˜๋ณต ํšŸ์ˆ˜๋ฅผ ์„ธ๋Š” ๊ฒƒ์œผ๋กœ ์ปฌ๋ ‰์…˜์˜ ์ ์ ˆํ•œ ์ธ๋ฑ์Šค๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

NSArray *array = <#๋ฐฐ์—ด ๊ฐ€์ ธ์˜ค๊ธฐ#>;
NSUInteger index = 0;
 
for (id element in array) {
    NSLog(@"์ธ๋ฑ์Šค %u์˜ ์š”์†Œ: %@", index, element);
    index++;
}

์ •๋ฆฌ

๋น ๋ฅธ ์—ด๊ฑฐ๋Š” Objective-C์—์„œ ์ปฌ๋ ‰์…˜์„ ํšจ์œจ์ ์œผ๋กœ ์ˆœํšŒํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ๊ฐ„๊ฒฐํ•œ ๊ตฌ๋ฌธ๊ณผ ์•ˆ์ „ํ•œ ์—ด๊ฑฐ ๊ธฐ๋Šฅ์€ ์ฝ”๋“œ๋ฅผ ๋” ์ฝ๊ธฐ ์‰ฝ๊ณ  ๊ฒฌ๊ณ ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. Foundation ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๋ชจ๋“  ์ปฌ๋ ‰์…˜ ํด๋ž˜์Šค์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด, iOS/macOS ๊ฐœ๋ฐœ์—์„œ ๋งค์šฐ ์œ ์šฉํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.