[15일차]일반 오브젝트 아카이브 Objective-C2010. 5. 27. 21:03
1. 일반 오브젝트 아카이브
일반 오브젝트를 아카이브 할 때는 NSCoding 프로토콜에 정의되어 있는 encodeWithCoder:와 initWithCoder: 메서드를 정의하면 됩니다.
메서드의 원형
-(void)encodeWithCoder:(NSCoder *)encoder
이 메서드의 안에서 encoder가 아카이브 할 실제 멤버들을 직접 인코딩하면 됩니다.
-(id) initWithCoder:(NSCoder *)decoder
이 메서드의 안에서 decoder가 언아카이브 할 실제 멤버들을 직접 디코딩하면 됩니다.
2. NSData를 이용한 아카이브
여러 개의 데이터를 아카이브 해야 하는 경우 NSData를 이용해서 이러한 작업을 수행할 수 있습니다.
이 때는 NSData를 이용해서 미리 영역을 설정한 후 이를 아카이브 클래스의 오브젝트에 연결한 후 이들을 아카이브 해나가면 됩니다.
------------------------------------------------------------
//Achive
#import <Foundation/NSObject.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSString.h>
#import <Foundation/NSKeyedArchiver.h>
#import <Foundation/NSCoder.h>
#import <Foundation/NSData.h>
@interface Test : NSObject<NSCoding>
{
NSString * str;
int n;
float f;
}
-(void)setStr:(NSString *)msg;
-(NSString *)str;
-(void)setN:(int)temp;
-(int)n;
-(void)setF:(float)temp;
-(float)f;
@end
@implementation Test
-(void)setStr:(NSString *)msg
{
str = [NSString stringWithString:msg];
}
-(NSString *)str
{ return str; }
-(void)setN:(int)temp
{ n = temp; }
-(int)n
{ return n;}
-(void)setF:(float)temp
{ f = temp; }
-(float)f
{return f; }
-(void) encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:str forKey:@"TestSrt"];
[encoder encodeInt:n forKey:@"TestN"];
[encoder encodeFloat:f forKey:@"TestF"];
}
-(id) initWithCoder:(NSCoder *)decoder
{
str = [decoder decodeObjectForKey:@"TestSrt"];
n = [decoder decodeIntForKey:@"TestN"];
f = [decoder decodeFloatForKey:@"TestF"];
}
@end
int main ()
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Test *Obj1 = [ [ Test alloc] init];
Test *Obj2 = [ [ Test alloc] init];
NSMutableData *dataArea; //nsData로 선언하면 Data변경이 안됨
NSKeyedArchiver *archiver;
[Obj1 setStr:@"Hello World"];
[Obj1 setN: 111];
[Obj1 setF: 11.1];
[Obj2 setStr:@"Objective-C"];
[Obj2 setN: 222];
[Obj2 setF: 22.2];
dataArea = [NSMutableData data]; // "data"는 생성자 , mutable 에서만 호출가능
archiver = [[ NSKeyedArchiver alloc] initForWritingWithMutableData: dataArea];
[archiver encodeObject:Obj1 forKey: @"Obj1"];
[archiver encodeObject:Obj2 forKey: @"Obj2"];
[archiver finishEncoding];
if (( [ dataArea writeToFile:@"myArchive" atomically:YES ] ) == NO)
NSLog(@"아카이빙 실패");
[Obj1 release];
[Obj2 release];
[pool drain];
system("pause");
return 0;
}
------------------------------------------------------------
------------------------------------------------------------
//UnAchive
#import <Foundation/NSObject.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSString.h>
#import <Foundation/NSKeyedArchiver.h>
#import <Foundation/NSCoder.h>
#import <Foundation/NSData.h>
@interface Test : NSObject<NSCoding>
{
NSString * str;
int n;
float f;
}
-(void)setStr:(NSString *)msg;
-(NSString *)str;
-(void)setN:(int)temp;
-(int)n;
-(void)setF:(float)temp;
-(float)f;
@end
@implementation Test
-(void)setStr:(NSString *)msg
{
str = [NSString stringWithString:msg];
}
-(NSString *)str
{ return str; }
-(void)setN:(int)temp
{ n = temp; }
-(int)n
{ return n;}
-(void)setF:(float)temp
{ f = temp; }
-(float)f
{return f; }
-(void) encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:str forKey:@"TestSrt"];
[encoder encodeInt:n forKey:@"TestN"];
[encoder encodeFloat:f forKey:@"TestF"];
}
-(id) initWithCoder:(NSCoder *)decoder
{
str = [decoder decodeObjectForKey:@"TestSrt"];
n = [decoder decodeIntForKey:@"TestN"];
f = [decoder decodeFloatForKey:@"TestF"];
}
@end
int main ()
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSData *dataArea;
NSKeyedUnarchiver *unarchiver;
Test *Obj1, *Obj2;
dataArea = [NSData dataWithContentsOfFile: @"myArchive"];
if (dataArea == nil)
{
NSLog(@"읽어 오기 실패");
return 0;
}
unarchiver = [[ NSKeyedUnarchiver alloc] initForReadingWithData: dataArea];
Obj1 = [unarchiver decodeObjectForKey: @"Obj1"];
Obj2 = [unarchiver decodeObjectForKey: @"Obj2"];
[unarchiver finishDecoding];
NSLog(@"Obj1의 데이터");
NSLog(@"==============");
NSLog(@"\n%@\n%i\n%g", [Obj1 str], [Obj1 n], [Obj1 f]);
NSLog(@"==============");
NSLog(@"Obj2의 데이터");
NSLog(@"==============");
NSLog(@"\n%@\n%i\n%g", [Obj2 str], [Obj2 n], [Obj2 f]);
[unarchiver release];
[pool drain];
system("pause");
return 0;
}
------------------------------------------------------------
ex>archive를 이용한 오브젝트의 복사(깊은 복사)
#import <Foundation/Foundation.h>
int main ()
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSData *data;
NSMutableArray *ar1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"1"], [NSMutableString stringWithString:@"2"],[NSMutableString stringWithString:@"3"],nil];
NSMutableArray *ar2;
NSMutableString *str;
int i;
data = [NSKeyedArchiver archivedDataWithRootObject: ar1];
ar2 = [NSKeyedUnarchiver unarchiveObjectWithData: data];
str = [ar1 objectAtIndex: 0];
[str appendString: @"1"];
NSLog(@"ar1: ");
NSLog(@"=================");
for(i=0; i<[ar1 count]; i++ )
NSLog(@"%@", [ar1 objectAtIndex:i]);
NSLog(@"=================");
NSLog(@"ar2: ");
NSLog(@"=================");
for(i=0; i<[ar2 count]; i++ )
NSLog(@"%@", [ar2 objectAtIndex:i]);
[pool drain];
system("pause");
return 0;
}
------------------------------------------------------------
** 예외처리
1. 예외처리를 위한 예약어
@try: Exceptions이 던져질 수 있는 block을 정의합니다.
@throw Exception object를 던진다.
@catch() @try bolck안에서 던져진 exception을 catch한다.
@finally @try block에서 Exceptions가 던져지던 아니던 수행되어질 block code를 정의한다.
모두 NSException.h에 정의되어 있습니다.
2. NSAssert (메서드 안에서 작성)
특정 조건을 만족하지 않는 경우 NSInternalInconsistencyException예외를 발생시켜 프로그램을 강제로 중단시키는 매크로함수
사용방법
NSAssert(만족해야 하는 조건, 출력할 문장);
==> 조건을 만족하지 않으면 Excception 발생시킨후 출력내용 출력