頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


構造体を入れた配列をNSDataに変換したい

構造体を入れた配列(NSArray)をNSDataに変換しようとしたらはまっちゃったよ。

↓まずはこういう構造体があるとするよ。
typedef struct {
    int age;
    NSString *name;
} Person_t;
そもそも構造体だとNS(Mutable)Arrayには入らないからNSValueに変換してNS(Mutable)Arrayに入れていたのよ。 配列とのやりとりはこんなカテゴリで。
@implementation NSMutableArray (AddPersonInfo)
-(void)addPersonInfo:(Person_t)personInfo
{
    NSValue *value = [NSValue value:&personInfo withObjCType:@encode(Person_t)];
    [self addObject:value];
}
@end

@implementation NSArray (GetPersonInfo)
-(Person_t)personInfoAtIndex:(int)index
{
    NSValue *value = [self objectAtIndex:index];
    Person_t personInfo;
    [value getValue:&personInfo];
    return personInfo;
}
@end
この方法で配列NS(Mutable)ArrayにどんどんaddしてできたNSMutableArrayオブジェクトをNSData化したくなったんだよ。CoreDataで持たせる、MultipeerConnectivityで送信する、、、みたいにNSData化したい時ってあるよね。
理由はともかくこのNSMutableArrayオブジェクトをNSData化しようと次のようなコードを書いたんだよ。
{
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
}
ホントはこれもカテゴリ化してるんだけどそれはどうでもいいや。
ともかくこれを実行すると落ちるのよ。
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSKeyedArchiver encodeValueOfObjCType:at:]: this archiver cannot encode structs'

え?構造体はだめなの?NSValueにしてるからいいのかと思ったんだけど。
ところがね、配列に入れる時にNSValueじゃなくてNSDataにしてみたんだよ。こういう感じのメソッドを用意しといてさ。
#pragma mark 変換処理(構造体←→NSData)
-(NSData *)dataFromPersonInfo:(Person_t)personInfo
{
    //NSDataに変換する
    return [NSData dataWithBytes: &personInfo length: sizeof(Person_t)];
}

-(Person_t)personInfoFromData:(NSData *)data
{
    //NSDataからPerson_tを得る
    Person_t personInfo;
    [data getBytes:&personInfo length:sizeof(Person_t)];
    return personInfo;
}
すると、その配列はすんなりとNSData化できたのよ!どういうこと?

構造体→NSValue→配列に入れる→NSData化 失敗
構造体→NSData→配列に入れる→NSData化 成功

配列にどんな形で入れるか?というだけなんだけどねえ。
ちなみにNSValueもNSDataもNSCodingプロトコルに準拠してるからどちらでも成功しそうなものなんだけど、、、そうならないのはきっと俺が何か理解していないんだろうな。

ともかくNSDataにしたいのなら構造体ではなくNSCodingプロトコルに準拠したクラスでやっとけって話だよね。

<< Blenderでレンダリング結果が真っ黒な理由  TopPage  SyntaxHighlighterでXcode風に表示 >>

コメント


管理者にだけ表示を許可する
 

トラックバック

トラックバックURL
http://ringsbell.blog117.fc2.com/tb.php/831-2304a935




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.

FC2Ad