Category Archives: プログラミング言語

Objective-Cの既存のクラスを拡張する仕組み

0
Filed under iPhone, Objective-C, プログラミング言語
Tagged as , , , , ,

Objective-Cには「カテゴリ」という機能があり、それについて調べたときのメモをまとめました。

その名は「カテゴリ」

ネットに転がっているソースを見ていて、それまで見たことなかった書き方があったときにはそれをどうやって調べたらいいのか、なかなか手こずります。その書き方そのものの名を知らないからです。
今回の例で言うと「カテゴリ」という機能のことで、下記のような感じで書かれていたら、それはカテゴリ機能を使っているのです。

1
@inteface NSString (HogeHoge)

このカテゴリ機能を活用すると、既存のクラスをちょっと機能拡張したい時に無駄なクラスを作る必要がなくなります。
例えば、文字列を扱うクラス NSString をに機能を追加したいことはよくあるのですが、NSStringの中身に応じたハッシュ値(MD5)を出力できるようなメソッドを追加する、という例に説明してみます。
MD5の機能実装の参考にしたのはこちらのサイト。関数の中身は全く同じです。

ざっくりしたカテゴリの書き方と使い方

まず、カテゴリ定義の書き方。
NSStringにMD5の機能を追加する場合、ファイル名は、NSString+MD5.h, NSString+MD5.m とするのがマナーのようです。
また、後述するソースを見ると分かるのですが、定義部は @inteface NSString (MD5)、実装部は @implementation NSString (MD5) という感じにして、あとは通常のクラス定義と同じように書きます。
次に使い方ですが、#import “NSString+MD5.h” として一緒にビルドすれば、そのソース内でNSStringインスタンスは全てMD5カテゴリの機能を持つことが出来ますので、下記のようなコードでMD5値を出力させることが出来ます。

1
2
NSString* strTest = @"テスト文字列";
NSLog( @"original[%@], MD5[%@]", strTest, [strTest MD5String] );

NSString+MD5 コード全容

1
2
3
4
5
6
7
//  NSString+MD5.h
 
#import <Foundation/Foundation.h>
 
@interface NSString (MD5)
- (NSString*) MD5String;
@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//  NSString+MD5.m
 
#import "NSString+MD5.h"
#import <CommonCrypto/CommonDigest.h> // for CC_MD5
 
@implementation NSString (MD5)
- (NSString *) MD5String
{
  const char *cStr = [self UTF8String];
  unsigned char result[CC_MD5_DIGEST_LENGTH];
  CC_MD5( cStr, strlen(cStr), result );
  return [NSString stringWithFormat:
    @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
    result[0], result[1], result[2], result[3], 
    result[4], result[5], result[6], result[7],
    result[8], result[9], result[10], result[11],
    result[12], result[13], result[14], result[15]
    ];  
}
@end

iOS SDKのMD5関数についての説明

おまけとして、上記のソースの内容を説明します。
MD5への変換関数 CC_MD5はiOS SDKにC言語ライブラリが用意されています。(リファレンスはこちら

CC_MD5は、次のように定義されています。

1
2
extern unsigned char*
CC_MD5(const void *data, CC_LONG len, unsigned char *md);

data が元になるデータのポインタ。
len がdataの長さ。
md がMD5計算の結果を格納する出力用バッファへのポインタで、CC_MD5_DIGEST_LENGTHの長さが必要なので、予め用意しておきます。本当はCC_MD5_DIGEST_LENGTHの長さに合わせて、出力部分を対応できるよう書いておく必要がありますが、CC_MD5_DIGEST_LENGTHは、そうそう16から変わることはないので、出力部分を固定で16要素並べてstringWithFormatで出力させています。

クラスの機能分割、という視点

カテゴリについての詳しい説明は、「Dynamic Objective-C」という書籍にも3ページに渡って説明されているのですが、こちらでの視点はチョット違う。

Dynamic Objective-C

著者/訳者:木下 誠

出版社:ビー・エヌ・エヌ新社( 2009-03-27 )

定価:¥ 3,360

Amazon価格:¥ 3,360

単行本(ソフトカバー) ( 456 ページ )

ISBN-10 : 4861006414

ISBN-13 : 9784861006418


そのセクション名は「カテゴリ ―動的なメソッドの追加によるクラスの拡張」となっていながらも、最初の段落の説明は次にように書かれている。

Objective-Cには、カテゴリと呼ばれる機能がある。クラスが持つメソッドを、名前の通りカテゴリごとに分類するための機能だ。これを使うことで、大きなクラスでもコーディングしやすいように分割することができる。

そもそもカテゴリとは、クラス実装を分割するための仕組み、だというのだ。
なるほど、そう考えるとカテゴリが「カテゴリ」という名前の由来もわかるし、ウェブに転がるサンプルのファイル名がHOGEHOGE-FOO.hとかハイフン繋ぎになっているモノがあるのも理解できる。
MVCモデルでクラスを分けても大きくなってしまうクラスはあるし、その場合にはカテゴリを使った機能分割も視野に入れていいかもしれない。
その他にもObjective-Cの深いところをじっくり説明してくれている「Dynamic Objective-C」はおすすめ書籍です!

カテゴリで出来ないこと

後から知ったのですが、カテゴリ機能で「クラスのインスタンス変数の追加」は出来ないようですね。
これ、結構重要なポイントだと思います。

参考サイト:『kuro’s blog : Objective-C:カテゴリで「できること」と「できないこと」』


[AD]

↓「CHAPTER09 カテゴリ」とカテゴリについて章を割いて説明されているようです!

詳解 Objective-C 2.0 改訂版

著者/訳者:荻原 剛志

出版社:ソフトバンククリエイティブ( 2010-12-17 )

定価:¥ 3,990

Amazon価格:¥ 3,990

大型本 ( 608 ページ )

ISBN-10 : 4797361786

ISBN-13 : 9784797361780


↓昨年8月に亡くなった今敏が1985年〜1986年に連載していたマンガ!面白そう!

OPUS(オーパス)上(リュウコミックス) [コミック]

著者/訳者:今 敏

出版社:徳間書店( 2010-12-13 )

定価:¥ 980

Amazon価格:¥ 980

コミック ( ページ )

ISBN-10 : 4199502211

ISBN-13 : 9784199502217


↓PS3もXbox360も持っていないけど、これは面白そう!

キャサリン 特典 サントラCD付き

キャサリン 特典 サントラCD付き

定価:¥ 7,329

Amazon価格:¥ 4,980

カテゴリ:Video Game

発売日:2011-02-17


Objective-CでNSStringプロパティ実装

0
Filed under Objective-C, プログラミング言語
Tagged as , , , , ,

Objective-Cをなんとなく使い続けていたのですが、分かってるようであまり分かっていなかったのがプロパティ
retain/release/autorelease周りとの絡みもあってなんとなくやり過ごしていたのですが、ちょっと切羽詰ってきたので仕切りなおして勉強してみました。

NSStringを持つクラスでテスト

いろいろ調べた結果、とりあえず、下記のようなクラスStringContainerを定義しておけば問題なく使えるっぽいです。(問題見つけたら教えてください!)
まずは、定義ファイル。内部にNSString*のインスタンス変数を二つと、そのプロパティ宣言を行っています。
重要なポリシーは、propertyは内部でコピーする、ということ。下記のページを参考にしています。

1
2
3
4
5
6
7
8
9
10
11
12
13
//  StringContainer.h
#import <Foundation/Foundation.h>
 
@interface StringContainer : NSObject {
	NSString*	str0;
	NSString*	str1;
}
 
// コピーするので、渡すものはautoreleaseしておいてください.
@property (nonatomic,copy) NSString* str0;
@property (nonatomic,copy) NSString* str1;
 
@end

次に実装コードです。プロパティ設定のためのsynthesizeと、デストラクタを定義しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//  StringContainer.m
#import "StringContainer.h"
 
@implementation StringContainer
 
@synthesize str0, str1;
 
-(void) dealloc{
	[super dealloc];
 
	[str0 release];
	[str1 release];
}
 
@end

そして、テストコード。str0とstr1では別の与え方をしてみました。

1
2
3
4
5
6
7
8
// Test.m
// 確保.
StringContainer* scTest;
scTest = [[StringContainer alloc] init];
 
// 各パラメータを設定.
scTest.str0	= [NSString stringWithFormat:@"Default 0[%d]",0];
scTest.str1	= [[[NSString alloc] initWithFormat:@"Changed 1[%d]",11] autorelease];

str0に渡す文字列は、stringWithFormatはクラスメソッドで生成。なので、そこで生成されたオブジェクトはそちらでAutoRelease Poolに入っているようなので、特にrelease/autoreleaseを行う必要はありません。むしろ、それをやると、retain countが0になったときに、二重にreleaseが呼ばれるので、問題となります。
str1に渡す文字列は、alloc, initで生成したもの。ここで生成しているので、ここでautoreleaseしています。代入後に即releaseしても問題有りませんが、ここでrelease/autoreleaseのどちらかを行っていないと、そのメモリは破棄されないので、リークしてしまいます。

これでOKのハズ!

一応、Instrumentsツールを使ってリークを調べたりもしたので、これで大丈夫だと思うのですが、認識に問題があったら誰か教えて欲しいです!!!
たったこれだけのことを自信持ってかけるようになるのに半日かかりました!
AutoRelease Poolというものの存在、クラスメソッドで定義したものがそちらで勝手にautoreleaseされているっぽい、ということ、それらをググって知ったので理解できたのですが、そうでなかったらなかなか辿り着けないのです。
ちなみに、NSArrayも同様な書き方でプロパティ実装できるはずです。


[AD]
↓この本、買いました!ウェブで連載されていたコラムの総集編とiPhone Hackコラムの書き下ろし。読み物として書かれているので、飽きずに読めてる!Objective-Cの実装部分まで踏み込んでいるので、ダイナミック言語としての面白さを知ることができるし、後半ではデザインパターンの実装の話にもなる。

Dynamic Objective-C

著者/訳者:木下 誠

出版社:ビー・エヌ・エヌ新社( 2009-03-27 )

定価:¥ 3,360

Amazon価格:¥ 3,360

単行本(ソフトカバー) ( 456 ページ )

ISBN-10 : 4861006414

ISBN-13 : 9784861006418



↓これも店頭で見ていい!と思って買いました。iPhoneプログラムのコネタ集なんだけど、一つ一つが過不足無く説明とコードが書かれていて、本当にすばらしい!版型もちょっと小さいので、鞄に入れて移動中に気になるところをちょっとずつ読むスタイルもオススメ。

iPhoneSDK開発のレシピ

著者/訳者:高山 恭介 広部 一弥 松浦 晃洋

出版社:秀和システム( 2010-03 )

定価:¥ 2,520

Amazon価格:¥ 2,520

単行本 ( 319 ページ )

ISBN-10 : 4798025798

ISBN-13 : 9784798025797


Googleの新言語「NOOP」

0
Filed under プログラミング言語
Tagged as

NOOP

Googleが「NOOP」という新プログラミング言語を公開したらしい。
http://code.google.com/p/noop/
ちなみに発音は「ヌープ」ではなく、「ノープ」のようです。

JavaVMで動作する

おもしろいなぁ、と思うのはJavaVMをつかうところ。
他人のふんどしで相撲を取る、というわけじゃないけど、よその土俵に上がり、そこで元いた相撲取り(Java)より良い相撲を取ろう、というわけだ。
いろいろなVMをプラットフォームとして考えるとおもしろいかもしれない。
まぁ、これがAndroid上で動作するってことまで考えるとなかなか面白い。
あ、でも、GroovyもJavaVMで動作、とかだったから、多言語のVMで動作するって、いろいろあるのかな。
Haxeも多言語のVMで動作する言語か。割とあるなぁ。

言語仕様

仕様ドキュメントはみていないのですが、今年8月にNOOPについて発表しているスライドがあるので、それを見てみました。これだけで概要と設計思想が分かります。

継承を使わないで、コンポジション+Delegateを使う方法を採用しているようです。
他にも、すべてはObject、static変数・関数は使わない、とか、現代的な仕様であることがわかります。
この仕様から、言語のトレンドも垣間見えて面白いドキュメント

私は、、

Android開発とかやらない限り、実際に使うことはしばらくなさそうですが、気になる言語として記憶しておきます。

Railという言語

0
Filed under xyzzy, プログラミング言語
Tagged as

おもしろいプログラミング言語を知ったので、メモ。

Rail

それはRailという名前のプログラミング言語です。

Railは、なんとテキストエディタで2次元的にフローを書ける言語なのです。
この言語のおもしろさがよく分かるソースが下図になります。これはソースコード(テキスト)なのです!
Rail y.railただ、これを普通のテキストエディタで書くのはかなり厳しい。
Emacsとかで何かしら専用のモードがあればいいですね。
あと、フォントもRailの仕様に合わせて綺麗に線がつながるものがあると楽しそう。

試してみた

インタプリタのソースは公開されているようで、以下のURLからダウンロードできる。

このzipファイルの中にはrail.exeというインタプリタが含まれており、examplesディレクトリ以下にあるrail拡張子のソースを渡すと実行される。

xyzzyのbox-drawings-mode

ちなみにxyzzyにはbox-drawings-modeという罫線描画モードがある。
自分の環境では全角の罫線文字を使うので、Railには使えないが、たまに使うと楽しい。
簡単な使い方をメモしておきます。
Controlを押しながらカーソルキーを押すと、その方向に罫線が描画され、さらにShiftを押しておくとその場所にある罫線が消える
Read More »