본문 바로가기

Dev/Objective-C

(펌) NSMutableArray, NSArray, 배열의생성과요소접근, 배열

NSArray와 서브클래스인 NSMutableArray에 대하여 가장 설명이 쉽고 깔끔하게 정리된곳이 있어 소개드립니다.


다음은 아래의 본문이고 도움이 되었다면 본문 포스트에 감사인사라도 전해드립시다  !


=================================================================

NSMutableArray, NSArray, 배열의생성과요소접근, 배열 (http://pooh4880.blog.me/100127603084)

Post By. 서니블록(pooh4880)님

=================================================================

배열
1. 배열 객체의 종류
Foundation 배열은 인스턴스의 연속된 모임입니다.
일반적인 언어에서는 배열의 원소는 특정한 하나의 자료형으로 구성되지만 여러 자료형으로 만들 수도 있습니다.
배열도 2가지가 있습니다.
수정이 불가능한 NSArray 과 수정이 가능한 NSMutableArray이 있습니다.

 

2. NSArray의 생성과 요소 접근
1) NSArray의 생성
NSArray * 배열명 = [NSArray arrayWithObjects: 인스턴스 나열.., nil]; //Objects면 nil, Object면 안씀. = s가 붙으면 nil을 쓴다.
배열 원소의 나열이 끝나면 마지막에 nil을 삽입해야 합니다. 
nil은 배열 원소의 끝을 나타내는 것으로 실제로 저장되지는 않습니다.
다른 배열로부터의 복사해서 초기화
-(id)initWithArray:(NSArray *)anArray
-(void) getObjects: (id *)aBuffer : C 형태의 배열에서 복사


배열에 객체가 대입될 때는 retain이 되어서 삽입됩니다.
배열이 삭제되거나 배열에서 데이터가 제거될 때 요소에게 release를 강제합니다.

-> 배열(컬렉션) 생성에 객체를 이용하거나 추가하면 retain이 발생한다.

-> 배열(컬렉션)이 소멸되거나 배열에서 요소가 제거될 때는 release가 발생한다.
cf. 컬렉션 : NSArray, NSSet, NSDictionary

 

2) NSArray의 요소 접근
[배열이름 count] => 배열의 요소 개수 리턴
[배열이름 objectAtIndex: 인덱스] : 메서드를 이용해서 리턴 받을 수 있습니다. -> 몇 번째껄 가져올껀지 쓰면 됨
[배열이름 indexOfObject:(id)anObject] : anObject가 배열에 있으면 첫번째 위치를 리턴하고 찾지 못하면 NSNotFound를 리턴합니다.
-(id)lastObject: 마지막 인스턴스 리턴
 
 
배열의 생성과 요소접근 예제

01.#import <Foundation/Foundation.h>
02.int main(int argc, char *argv[])
03.{
04.NSAutoreleasePool * pool = [NSAutoreleasePool new];
05.int i;
06.NSNumber *num = [[NSNumber alloc]initWithInt:100];
07.// alloc되었으므로 retainCount = 1
08.NSLog(@"num의 retainCount: %d",[num retainCount]); //1
09.// 배열에 num이 추가되었으므로 num의 retainCount는 1 증가
10.NSArray * ar = [NSArray arrayWithObjects: @"Morning",@"Afternoon",@"Evening",num, nil]; //모닝, 애프터눈, 이브닝, 100
11.// 배열의 모든 요소에 접근해서 출력
12.for (i = 0; i < [ar count]; i++)
13.NSLog(@"%@", [ar objectAtIndex: i] ); //objectAtIndex를 이용하여 o부터 arcount(4)까지 순서대로 i를 가져옴
14.// num의 retainCount = 2
15.NSLog(@"num의 retainCount: %d",[num retainCount]); //2
16.// 배열이 소멸되거나 배열에서 요소가 제거될 때 요소에는 release가 발생
17.// 배열이 제거
18.[ar release];
19.// num의 retainCount = 1
20.NSLog(@"num의 retainCount: %d",[num retainCount]); //1
21.[num release];
22.[pool drain];
23.return 0;
24.}

결과
2010-11-10 11:19:10.885 Test[1600:a0f] num의 retainCount: 1
2010-11-10 11:19:10.887 Test[1600:a0f] Morning
2010-11-10 11:19:10.888 Test[1600:a0f] Afternoon
2010-11-10 11:19:10.888 Test[1600:a0f] Evening
2010-11-10 11:19:10.889 Test[1600:a0f] 100
2010-11-10 11:19:10.889 Test[1600:a0f] num의 retainCount: 2
2010-11-10 11:19:10.890 Test[1600:a0f] num의 retainCount: 1
  
3. NSArray의 기타 메서드
-(BOOL)isEqualToArray:(id)anObject : 배열의 요소 개수와 모든 멤버가 동일하면 YES 아니면 NO를 리턴
-(id)firstObjectCommonWithArray:(NSArray *)otherArray : 일치하는 첫번째 인스턴스 리턴
-(NSArray *)arrayByAddingObject:(id)anObject : 인스턴스를 추가해서 만들어진 배열을 리턴
-(NSArray *)arrayByAddingObjectsFromArray:(NSArray *)anArray : 배열을 추가해서 만들어진 배열을 리턴
-(NSArray *)sortedArrayUsingSelector:(SEL)comparator : comparator에 지정된 메서드를 기준으로 오름차순 정렬하여 리턴
 sorting을 하려면 아래 메서드를 구현해야 함
 - (NSComparisonResult) 메서드명 : (자신의 클래스타입 *)객체; 
Foundation 클래스(NSNumber, NSString)은 비교하는 메서드가 있으므로 이 메서드로 가능
compare : 대소문자 구별, 소문자는 대문자 뒤로 감
caseInsensitiveCompare : 대소문자 구별 안함

일반 클래스인 경우는 자신의 타입과 비교해서 NSComparisonResult로 리턴하는 메서드가 있어야가능합니다.
 
 

01.#import <Foundation/Foundation.h>
02.int main(int argc, char *argv[])
03.{
04.NSAutoreleasePool * pool = [NSAutoreleasePool new];
05.int i;
06.NSArray * ar = [NSArray arrayWithObjects: @"morning",@"Morning",@"Afternoon",@"Evening", nil];
07.ar = [ar arrayByAddingObject:@"Night"];//Night추가
08. 
09.// compare 대신에 caseInsensitiveCompare를 이용하면 대소문자 구별없이 비교
10.ar = [ar sortedArrayUsingSelector:@selector(compare:)];
11.for (i = 0; i < [ar count]; i++)
12.NSLog(@"%@", [ar objectAtIndex: i] );
13.[pool drain];
14.return 0;
15.}

결과
2010-11-10 11:35:14.070 Test[1841:a0f] Afternoon
2010-11-10 11:35:14.072 Test[1841:a0f] Evening
2010-11-10 11:35:14.073 Test[1841:a0f] Morning
2010-11-10 11:35:14.073 Test[1841:a0f] Night
2010-11-10 11:35:14.073 Test[1841:a0f] morning
 
예제


1. Test.h파일

01.#import <Foundation/Foundation.h>
02.@interface Test : NSObject
03.{
04.int number;
05.int rank;
06.NSString * name;
07.}
08.//멤버 변수들에 대한 프로퍼티 선언
09.//nonatomic은 상호배제코드를 넣지 않는다 = 속도 빠름
10.//retain은 객체사이의 대입이 이루어질 때 retain으로 대입
11.@property (nonatomic) int number;
12.@property (nonatomic) int rank;
13.@property (nonatomic, retain) NSString * name;
14.//초기화해주는 메서드 : 객체가 생성되는 순서대로 number의 일련번호를 대입.
15.-(id)init;
16.//rank를 비교해서 그 결과를 리턴해주는 메서드
17.-(NSComparisonResult)rankCompare:(Test *)Obj;
18.//name을 비교해서 그 결과를 리턴해주는 메서드
19.-(NSComparisonResult)nameCompare:(Test *)Obj;
20.@end


2. test.m파일

01.#import "Test.h"
02.@implementation Test
03.//일련번호를 만들기 위한 static변수
04.static int sequence = 1; // 일련번호 를 주기 위해서는 static변수를 이용.
05.//프로퍼티를 만들면 그에 해당하는 synthesize가 와야 한다.
06.@synthesize number;
07.@synthesize rank;
08.@synthesize name;
09.//init 메서드는 재정의하는 방법이 정해져 있다.
10.//self에게 [super init]을 넘겨주고 self가 nil이 아닐 때 초기화 코드를 수행하고 self를 리턴
11.-(id)init
12.{
13.if((self = [super init])!=nil)
14.{
15.//static변수인 sequence를 1씩 증가시키면서 number에 대입
16.number = sequence++;
17.}
18.return self;
19.}
20.//순위를 비교해서 그 결과를 리턴해주는 메서드
21.-(NSComparisonResult)rankCompare:(Test *)Obj // 순위를 가지고 비교
22.{
23.if(self.rank < Obj.rank) // 나와 상대방 비교
24.return NSOrderedAscending; //뒤가 크면 어센딩, 앞이 크면 디센딩
25.else if(self.rank == Obj.rank)
26.return NSOrderedSame;
27.else
28.return NSOrderedDescending; // 앞이 크면 디센딩
29.}
30.//name을 비교해서 리턴해주는 메서드 - name 은 NSString 이므로 compare나 caseInsensitiveCompare로 비교해야 한다.
31.-(NSComparisonResult)nameCompare:(Test *)Obj // 이름을 가지고 비교
32.{
33.if([self.name compare:Obj.name] == NSOrderedAscending) // 문자열의 비교 : compare
34.return NSOrderedAscending;
35.else if([self.name compare:Obj.name] == NSOrderedSame)
36.return NSOrderedSame;
37.else
38.return NSOrderedDescending;
39./* 줄여쓰고 싶다면 위 여섯줄을 없애고 아래처럼 해도 됨
40.return([self.name compare:Obj.name]);
41.-1을 곱해주면 내림차순 정렬 가능 */
42.}
43.@end


3. main 메서드가 있는 m파일

01.#import "Test.h"
02.int main (int argc, const char * argv[])
03.{
04.NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
05. 
06.//Test 타입의 객체 3개 생성
07.Test * Obj1 = [[Test alloc]init];
08.Obj1.rank = 2;
09.Obj1.name = @"이순신";
10. 
11.Test * Obj2 = [[Test alloc]init];
12.Obj2.rank = 3;
13.Obj2.name = @"김유신";
14. 
15.Test * Obj3 = [[Test alloc]init];
16.Obj3.rank = 1;
17.Obj3.name = @"안중근";
18. 
19.// 3개의 객체를 가지고 데이터배열 생성
20.NSArray * Data = [NSArray arrayWithObjects:Obj1, Obj2, Obj3, nil];
21.//객체가 배열에 추가되었으므로 retainCount가 2이므로 전부 release를 해서 1을 만든다.
22.[Obj1 release];
23.[Obj2 release];
24.[Obj3 release];
25. 
26.//배열에 있는 모든 요소를 출력
27.int i;
28.Test * imsi;
29.for(i=0; i<[Data count]; i++)
30.{
31.//배열에서 index(i)를 이용해서 데이터를 가져와 retain으로 imsi에 대입
32.imsi=[[Data objectAtIndex:i]retain];
33.NSLog(@"번호:%d 순위:%d 이름:%@",imsi.number, imsi.rank, imsi.name);
34.[imsi release];
35.}
36. 
37.//Data배열을 nameCompare라는 메서드에 따라 정렬
38.Data = [Data sortedArrayUsingSelector:@selector(nameCompare:)];
39.NSLog(@"이름 순으로 정렬");
40.NSLog(@"=====================");
41.for(i=0; i<[Data count]; i++)
42.{
43.imsi=[[Data objectAtIndex:i]retain];
44.NSLog(@"번호:%d 순위:%d 이름:%@",imsi.number, imsi.rank, imsi.name);
45.[imsi release];
46.}
47. 
48.//Data배열을 rankCompare라는 메서드에 따라 정렬
49.Data = [Data sortedArrayUsingSelector:@selector(rankCompare:)];
50.NSLog(@"성적 순으로 정렬");
51.NSLog(@"=====================");
52.for(i=0; i<[Data count]; i++)
53.{
54.imsi=[[Data objectAtIndex:i]retain];
55.NSLog(@"번호:%d 순위:%d 이름:%@",imsi.number, imsi.rank, imsi.name);
56.[imsi release];
57.}
58. 
59.[Data release];
60.[pool drain];
61.return 0;
62.}

결과
2010-11-10 12:07:44.383 Test[2151:a0f] 번호:1 순위:2 이름:이순신
2010-11-10 12:07:44.385 Test[2151:a0f] 번호:2 순위:3 이름:김유신
2010-11-10 12:07:44.385 Test[2151:a0f] 번호:3 순위:1 이름:안중근
2010-11-10 12:07:44.386 Test[2151:a0f] 이름 순으로 정렬
2010-11-10 12:07:44.386 Test[2151:a0f] =====================
2010-11-10 12:07:44.386 Test[2151:a0f] 번호:2 순위:3 이름:김유신
2010-11-10 12:07:44.387 Test[2151:a0f] 번호:3 순위:1 이름:안중근
2010-11-10 12:07:44.387 Test[2151:a0f] 번호:1 순위:2 이름:이순신
2010-11-10 12:07:44.387 Test[2151:a0f] 성적 순으로 정렬
2010-11-10 12:07:44.388 Test[2151:a0f] =====================
2010-11-10 12:07:44.388 Test[2151:a0f] 번호:3 순위:1 이름:안중근
2010-11-10 12:07:44.389 Test[2151:a0f] 번호:1 순위:2 이름:이순신
2010-11-10 12:07:44.389 Test[2151:a0f] 번호:2 순위:3 이름:김유신 
 
 


4. NSMutableArray
배열의 요소인 객체를 제거하거나 삽입할 수 있는 메서드가 제공되는 배열 클래스
-(id)initWithCapacity:(NSUinteger)numItems : numItems의 개수를 가진 배열을 생성
-(void)addObject:(id)anObject : anObject를 마지막에 추가
-(void)addObjectsFromArray:(NSArray *)otherArray : otherArray를 추가
-(void)insertObject:(id)anObject atIndex:(NSUinter)index : index 번째에 anObject 추가
-(void)replaceObjectAtInde:(NSUinter)index withObject:(id)anObject : index 번째에 Object를 anObject로 변경
-(void)setArray:(NSArray *)otherArray : 모든 내용을 초기화하고 otherArray로 변경
-(void)removeAllObjects : 모든 요소 제거
-(void)removeLastObjects : 마지막 요소 제거
-(void)removeObjectAtIndex : (NSUinter)index   :   index 번째 제거
-(void)removeObject:(id)anObject   :   anObject 찾아서 제거
 

01.#import <Foundation/Foundation.h>
02.int main(int argc, char *argv[])
03.{
04.NSAutoreleasePool * pool = [NSAutoreleasePool new];
05.int i;
06.NSMutableArray *mAr = [NSMutableArray arrayWithCapacity: 10]; // 처음 10칸 확보
07.[mAr addObject: [NSNumber numberWithInteger: 1]]; // 하나하나 추가하면서 만듬
08.[mAr addObject: [NSNumber numberWithInteger: 5]];
09.[mAr addObject: [NSNumber numberWithInteger: 7]];
10.for (i = 0 ; i < [ mAr count]; ++i)
11.NSLog (@"%d", [[mAr objectAtIndex: i] integerValue]); //1,5,7
12.[mAr insertObject: [NSNumber numberWithInteger: 3] atIndex:1];  // 첫번째 칸에 3을 넣음
13.NSLog(@"추가된 후");
14.for (i = 0 ; i < [ mAr count]; ++i)
15.NSLog (@"%d", [[mAr objectAtIndex: i] integerValue]); //1,3,5,7
16.[mAr replaceObjectAtIndex:1 withObject:[NSNumber numberWithInteger: 4]]; //첫번째 칸에 있는것을 4로 바꿔
17.NSLog(@"변경된 후");
18.for (i = 0 ; i < [ mAr count]; ++i)
19.NSLog (@"%d", [[mAr objectAtIndex: i] integerValue]); //1,4,5,7
20.[mAr removeObjectAtIndex:1];  //첫번째껄 지워라
21.NSLog(@"삭제된 후");
22.for (i = 0 ; i < [ mAr count]; ++i)
23.NSLog (@"%d", [[mAr objectAtIndex: i] integerValue]); //1,5,7
24.[pool drain];
25.return 0;
26.}

결과
2010-11-10 12:16:38.360 Test[2380:a0f] 1
2010-11-10 12:16:38.362 Test[2380:a0f] 5
2010-11-10 12:16:38.362 Test[2380:a0f] 7
2010-11-10 12:16:38.362 Test[2380:a0f] 추가된 후
2010-11-10 12:16:38.363 Test[2380:a0f] 1
2010-11-10 12:16:38.363 Test[2380:a0f] 3
2010-11-10 12:16:38.364 Test[2380:a0f] 5
2010-11-10 12:16:38.364 Test[2380:a0f] 7
2010-11-10 12:16:38.364 Test[2380:a0f] 변경된 후
2010-11-10 12:16:38.365 Test[2380:a0f] 1
2010-11-10 12:16:38.365 Test[2380:a0f] 4
2010-11-10 12:16:38.365 Test[2380:a0f] 5
2010-11-10 12:16:38.366 Test[2380:a0f] 7
2010-11-10 12:16:38.366 Test[2380:a0f] 삭제된 후
2010-11-10 12:16:38.367 Test[2380:a0f] 1
2010-11-10 12:16:38.367 Test[2380:a0f] 5
2010-11-10 12:16:38.368 Test[2380:a0f] 7

 

====================================
                  NSArray              NSMutableArray
삽입          가능(리턴)          가능(리턴안함)
추가          불가                    가능
교체          불가                    가능
삭제          불가                    가능
속도          빠름                    느림
====================================