336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
다음과 같이 버튼 하나 있고 내부적으로 배열을 가지고 있는 창이 하나 있다고 가정합니다. 버튼을 클릭하면 button_Click 메서드가 실행됩니다.
// TestDelegate.h #import <Cocoa/Cocoa.h> @interface TestDelegate : NSObject <NSApplicationDelegate> { NSArray * array; NSWindow * window; NSButton * button; } @property (nonatimic, retain) NSArray * array; @property (assign) IBOutlet NSWindow * window; @property (nonatomic, retain) IBOutlet NSButton * button; - (IBAction) button_Click: (NSButton *) sender; @end
// TestDelegate.m #import "TestDelegate.h" @implementation TestDelegate @synthesize array; @synthesize window; @synthesize button; - (void) applicationDidFinishLaunching: (NSNotification *) aNotification { self.array = [NSArray arrayWithObjects: [NSNumber numberWithInteger: 0], nil]; } - (IBAction) button_Click: (NSButton *) sender { NSLog(@"배열의 첫째 원소는 %d", [[[self array] objectAtIndex: 0] integerValue]); } @end
겉 보기에는 별 문제가 없어 보입니다.
앱이 실행되면 array 포인터가 NSArray의 arrayWithObjeccts: 메서드에 의해 초기화된 배열을 가지고 있고,
버튼을 클릭해서 button_Click이 실행되면 이 배열의 0번째 원소에 접근해서 콘솔에 값을 출력하는 것이니까요. 하지만 실제로 실행해보면 EXC_BAD_ACCESS 오류가 발생합니다.
applicationDidFinishLaunching이 끝나고 button_Click이 실행되기 전까지 array가 사용되지 않았으므로 저절로 메모리가 해제되어 버린 것입니다.
이 때는 array가 갖는 포인터를 Mac OS가 저절로 해제하지 않도록 지정해야 합니다. 대신, 해제하는 시점에 제대로 해제되도록 프로그래머가 직접 지정해야 합니다.
아래와 같이 NSArray형 인스턴스에 retain 메시지를 보내서 그 반환값을 멤버변수에 저장하면 액세스 위반 오류가 뜨지 않고 잘 실행됩니다.
self.array = [[NSArray arrayWithObjects: [NSNumber numberWithInteger: 0], nil] retain];
대신 dealloc 메서드를 재정의해서 직접 해당 배열을 해제해줘야 합니다.
// TestDelegate.h #import <Cocoa/Cocoa.h> @interface TestDelegate : NSObject <NSApplicationDelegate> { NSArray * array; NSWindow * window; NSButton * button; } @property (nonatimic, retain) NSArray * array; @property (assign) IBOutlet NSWindow * window; @property (nonatomic, retain) IBOutlet NSButton * button; - (void) dealloc; - (IBAction) button_Click: (NSButton *) sender; @end
// TestDelegate.m #import "TestDelegate.h" @implementation TestDelegate @synthesize array; @synthesize window; @synthesize button; - (void) applicationDidFinishLaunching: (NSNotification *) aNotification { self.array = [NSArray arrayWithObjects: [NSNumber numberWithInteger: 0], nil]; } - (void) dealloc { [[self array] release]; [super dealloc]; } - (IBAction) button_Click: (NSButton *) sender { NSLog(@"배열의 첫째 원소는 %d", [[[self array] objectAtIndex: 0] integerValue]); } @end
'Programming Language > Objective-C' 카테고리의 다른 글
Objective-C에서 SQLite 사용 예제 (0) | 2018.07.27 |
---|---|
NSDate로 현재 날짜 얻기 (0) | 2012.04.28 |
NSString과 C 문자열간 변환하기 (0) | 2012.02.26 |
Objective-C 첫 예제 (0) | 2012.01.21 |