頭と尻尾はくれてやる!

iOSアプリなどの開発日記です


構造体の定義部分にカテゴリで拡張しておく

頭と尻尾はくれてやる! NSMutableArrayのカテゴリを使って構造体を配列に出し入れしたい
↑この記事ではあきらめたって書いたんだけどその後ちょいと変更したんだ。
と言っても問題がすっきり解決したわけじゃなくて運用上の変更で対応したんだよ。

自分で作った構造体があるとして、、、例えばアドレス帳管理アプリの
typedef struct {
    NSString *name;
    int age;
    NSString *address;
} Address_t;
こんな構造体とかね。

通常この構造体の定義をどこでやるのかな?実は俺自身も今まで結構あいまいで単に「不具合が起きない場所」に置く程度だったんだよ。
最近コードの再利用を心がけるようになってから、定義専用の別ファイルを作っておいてそこに記述するようにしてるんだ。使う時にファイルでいちいちインポートするのが面倒なので、プロジェクトにあるpchファイルでインポートしてる。
別ファイルにして置く、と決めておくとどこに記述してあるかがすぐにわかるのがいいんだよね。
今回新たに追加したマイルールがこういう構造体を扱うカテゴリの記述を構造体の定義ファイルに一緒に記述しておく、ってこと。
これならカテゴリ記述部分はこの構造体は何者かってのがわかってるわけで次のように書けるんだよね。
//ヘッダーファイル(.h)
typedef struct {
    NSString *name;
    int age;
    NSString *address;
} Address_t;

@interface NSMutableArray (AddAddress_t)
-(void)addAddress:(Address_t)addressInfo;
@end

@interface NSArray (GetAddress_t)
-(Address_t)addressAtIndex:(int)index;
@end

//実装ファイル(.m)
@implementation NSMutableArray (AddAddress_t)
-(void)addAddress:(Address_t)addressInfo
{
    NSValue *value = [NSValue value:&addressInfo withObjCType:@encode(Address_t)];
    [self addObject:value];
}
@end

@implementation NSArray (GetAddress_t)
-(Address_t)addressAtIndex:(int)index
{
    NSValue *value = [self objectAtIndex:index];
    Address_t addressInfo;
    [value getValue:&addressInfo];
    return addressInfo;
}
@end
これでとりあえず
//追加時
{
    [array addAddress:addressInfo];
}
//取り出す時
{
    Address_t addressInfo = [array addressAtIndex:0];
}
みたいな記述が実現できるし、簡単に管理ができそうな気がするんだけどどうだろう。
不具合出てやめるようならまた追記するよ。





Skype支払い時に注意したいブラウザによる表示内容の違い

ここ数年Skypeを使っているんだ。
日本国内の固定電話への通話ができる月額プラン(60分)ってのに入ってるんだけど、1年の期限が切れたので再度申し込むことにしたんだ。

しばらくして気付いたんだけど、今まで使ってた固定電話へ通話できる60分の月額プランがなくなってて、120分からになってる!
プランの種類が変更されたのかあ、、、一ヶ月に120分も電話なんてしないしなあ、、、でもプリペイドだとSkype番号の50%割引効かないしなあ、、、いっそ050 plusとかどうよ?ってサイトをウロウロしてたりもしたんだ。

しばらくして気付いたのがブラウザでの表示の違い。

Skypeスクショ(Mac Safari)

↑これはMacのSafariで見た画面。

Skypeスクショ(Mac Firefox)

↑Firefoxの場合。

なぜかMacのSafariだと60分のプランは表示してくれない。
わざとなのか不具合なのかは知らないけど、、、ともかくFirefoxで無事購入。

まあ値段相応と思えばさほど腹も立たないけどね。


NSMutableArrayのカテゴリを使って構造体を配列に出し入れしたい

頭と尻尾はくれてやる! 構造体を配列に入れる方法
↑前に構造体を配列に入れる方法をメモしてたけどさ、
{
    [array addObject:[NSValue value:&clockInfo withObjCType:@encode(ClockInfo)]];
}
こんな感じでNSValueオブジェクトにしてから配列に入れるのがなんともまどろっこしいというか、理解しにくいというか。
おまけに取り出して使う時には
{
    ClockInfo clockInfo;
    [[array objectAtIndex:0] getValue:&clockInfo];
}
という具合なんだよね。一行で書けないんだ、、、
できることなら
{
    //追加
    [array addStruct:clockInfo];

    //取り出し
    ClockInfo clockInfo = [array structAtIndex:0];
}
みたいな感じで使えたらすごくわかりやすくていいんじゃね?って思ってNSMutableArrayのカテゴリでやってみたんだけどさ、、、
@implementation NSMutableArray (AddStructTest)
-(void)addStruct:(void *)structPointer
{
    NSValue *value = [NSValue value:structPointer withObjCType:@encode(void *)];
    [self addObject:value];
}
@end
↑こんな感じでNSMutableArrayのオブジェクトに追加するメソッドはできた。
実際、従来の方法で配列から取り出して使うこともできた。ここまではいいんだけどさ。
いざ取り出そうとしたんだけど、、、
@implementation NSMutableArray (GetStructTest)
-(void *)structAtIndex:(int)index
{
    NSValue *value = [self objectAtIndex:index];
    void *pointer;
    [value getValue:&pointer];
    return pointer;
}
NSValueオブジェクトを取り出すところまではいいんだけど、そこからgetValue:メソッドを使ってデータを指定した'住所'に展開する時にどうもうまくいかないんだよ。このメソッド実行時に正しい構造体の型というか中に何を持ってるかの情報が必要なのかな。ポインタだけしか情報がないからできないんだろうな。

ともかくこのカテゴリでどうこうするのはあきらめたよ、、、orz





クラスメソッドよりもカテゴリの方がなんとなくすっきりする

例えばNSString型の文字列があってそれをNSData型に変えたい、とするよ。
ネットを漁れば
{
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
}
なんてサンプルが見つかって一件落着。
でも、数ヶ月後か数年後かわからないけどまた同じ疑問にぶつかった時、俺はきっと同じことを繰り返すんだよね。いや、ホント時間の無駄。

だからこういう時、Xcodeの素晴らしい機能Code Snippetを使ってメモしておくってのはいいと思うんだ。ショートカットを設定しておけば一撃で表示できるし。

その他の方法だとクラスメソッドにしておくってのもやるんだ。
MyMethodsクラスなんて作っておいてそこに処理を書いておいて
{
    NSData *data = [MyMethods changeToDataFromString:string];
}
こんな感じで使うとか。
自分になじむメソッド名を付けられるのがいいところで後々このコードを見た時に理解しやすいのが利点。あー、自分で作ったメソッドなんだなってことも余裕でわかるし。


最近の好みはクラスメソッドよりもカテゴリを使って記述しておく方法。
@implementation NSString (ConvertToNSData)
-(NSData *)toData
{
     //NSStringをNSDataへ変換する
    return [self dataUsingEncoding:NSUTF8StringEncoding];
}
@end
↑こんな感じの記述をしておけば、実際に使う時は
{
    NSData *data = [string toData];
}
↑これだけになるのでかなりすっきりする。
{
    NSData *data = string.toData;
}
↑こういう書き方でもいいけど個人的にはあまりしっくりこないので上の方が好み。
この処理に限って言えば、型を変える処理にドット記法で記述するのがしっくりこないってとこかな。


CopyPasteCharacter.comをXcodeのコメントに使ってみる

CopyPasteCharacter.comイメージ図

✿ Our favorite set — CopyPasteCharacter.com
↑こういうサイトを偶然見つけたんだよ。

このサイトからのコピペでいろんなキャラクターや絵文字みたいなのを文字のように使えるんだ、、、不思議だな

ふと思い付いた使い道なんだけど、Xcodeでコメントする時にわかりやすいように絵で残しておきたいことがあってそれに使えるんじゃないかな、と。

CopyPasteCharacter.comでXcodeのコメント

⇧上が従来の、下がCopyPasteCharacter.comのを使った場合。うーん、あまり変わらなかったな

やっぱりXcodeで画像をコメントとして残せる機能を追加して欲しいね




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