構造体を入れた配列をNSDataに変換したい
構造体を入れた配列(NSArray)をNSDataに変換しようとしたらはまっちゃったよ。
↓まずはこういう構造体があるとするよ。
理由はともかくこのNSMutableArrayオブジェクトをNSData化しようと次のようなコードを書いたんだよ。
ともかくこれを実行すると落ちるのよ。
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSKeyedArchiver encodeValueOfObjCType:at:]: this archiver cannot encode structs'
え?構造体はだめなの?NSValueにしてるからいいのかと思ったんだけど。
ところがね、配列に入れる時にNSValueじゃなくてNSDataにしてみたんだよ。こういう感じのメソッドを用意しといてさ。
構造体→NSValue→配列に入れる→NSData化 失敗
構造体→NSData→配列に入れる→NSData化 成功
配列にどんな形で入れるか?というだけなんだけどねえ。
ちなみにNSValueもNSDataもNSCodingプロトコルに準拠してるからどちらでも成功しそうなものなんだけど、、、そうならないのはきっと俺が何か理解していないんだろうな。
ともかくNSDataにしたいのなら構造体ではなくNSCodingプロトコルに準拠したクラスでやっとけって話だよね。
↓まずはこういう構造体があるとするよ。
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
https://ringsbell.blog.fc2.com/tb.php/831-2304a935
https://ringsbell.blog.fc2.com/tb.php/831-2304a935