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 |