2011年6月29日水曜日

Googleからどどーん

Google+
http://gplusproject.appspot.com/static/ja.html
Googleの新たなSNSって感じで結構満を持して出したって感じがします。
Facebookとの違いはFacebookは友達にはすべて平等に公開ですが、
Google+では「サークル」という概念がありその中でのコミュニケーションといった感じでしょうか。
GoogleのSNSはダメというジンクスと、Facebookの牙城を切り崩せるのかというところがポイントですね。

Swiffy
http://googlecode.blogspot.com/2011/06/swiffy-convert-swf-files-to-html5.html
FlashをHTML5に変換するサービスです。
どこまで完成度が高いのかはGoogle labなのでよくわかりませんが、
Flashの終焉も刻々と近付いている感じがします。

Google Developer Day 2011 Japan
http://googledevjp.blogspot.com/2011/06/google-developer-day-2011-japan.html
GDD2011が11月1日@パシフィコ横浜で開催されます。
今年も参加するにはクイズに正解しないといけないみたいなのでがんばらないとです。

2011年6月19日日曜日

Objective-Cで気をつけるべき点

C++やJavaからObjective-Cを使うにあたって間違いやすい点や異なる点です。

同じオブジェクト指向言語といっても、言語によって慣習や考え方はかなり異なることがあります。
他の言語の慣習や考え方を持ち込むのは可読性を損ねるだけでなく、一貫性も損ねることとなるので言語の考え方や慣習はきちんと学ぶべきだと思います。


インスタンス変数はデフォルトはprotected
@privateを使うことでprivateにすることができます。publicも同様にできますが、カプセル化を阻害するのでもちろん推奨されていません。


メソッドはすべてpublic
ヘッダーファイルでプロトタイプ宣言してなくても、メッセージを送ると呼び出せますので、.mファイル側にだけ宣言していたとしてもprivateになったわけではありません。
Objective-C 2.0(iOS)であればクラスエクステンションを使うことで、ヘッダーファイルのほうにプロトタイプ宣言をしなくて済むのとクラスエクステンションを見るとどれがprivateメソッドなのか判定することができます。
privateメソッドに接頭語を付けて見分けるというのも合わせて使ったほうがいいかもしれません。
Extensions(The Objective-C Programming Language)

propertyのデフォルトはatomic
propertyはデフォルトはatomicになっているので無駄に排他制御がかかり性能に影響します。排他不要の場合はnonatomicを必ず書きましょう。

initでインスタンス変数はすべて0で初期化される
Javaと同様に初期化が自動でされるので、C++のようにコンストラクタで0で初期化する必要はありません。
Allocating and Initializing Objects(The Objective-C Programming Language)

nilのオブジェクトにメッセージを送っても無視されるだけでクラッシュはしない
C++のようにクラッシュ回避という意味でのnilチェックは不要です。nilチェックは通常ケースのハンドリングで使います。
Sending message to nil(The Objective-C Programming Language)

BOOLのYESは1とは限らないので、if文内での判定には使わないようにする。
BOOLはunsigned charと同じなので1以外の数が返ってくる恐れもあります。 == YES は避けたほうがよいです。

NSString,NSColor,NSURLはretainではなくcopyを使う
NSStringなどといった value objectsとよばれるオブジェクトにはcopyをつかったほうがよいそうです。
copyとして保持したり返したりするので不変であることが保証できるからのようです。
Value Objects and Copying(Memory Management Programming Guide)

string = value;
self.string = value;
は別物
全者は単なる代入ですが、後者はpropertyによって作られたアクセッサを使っています。後者だとpropertyの宣言によってただの代入だったりretainやcopyされたり排他がかかったりと動作が異なります。

delegateはretainしない
巡回参照による無限ループにはまらないようにdelegateはretainせず、参照だけを保持する。
Weak References to Objects(Memory Management Programming Guide)

メソッド名に接頭語は使わない。
doやdoesをつけるのも意味的な問題で推奨されていません。getも付けないのが慣習です。
General Rules(Coding Guidelines for Cocoa)

引数にキーワードをつける。
キーワードなしでもメソッドの宣言はできますが、キーワードをつける。
General Rules(Coding Guidelines for Cocoa)

プライベートメソッドは独自の接頭語をつけたほうがよい
知らないうちにオーバーライドしてしまうことを防ぐためと、プライベートメソッドを見分けやすくするために、接頭語をつける。ただしアンダーバーはAppleが使っているので独自のものを用意する。例えばBF_addObjectなど
Private Methods(Coding Guidelines for Cocoa)
Typographic Conventions(Coding Guidelines for Cocoa)

#defineは使わずenumもしくはconstを使う
C++と同じで#defineだとプリプロセッサで数値に置き換えられてしまうので、enum,constを使う。
Other types of constants(Coding Guidelines for Cocoa)

通常ケースのハンドリングでは例外は使わない。
JavaではFileNotFoundなど通常のハンドリングにも例外を使いますが、Objective-Cでは、配列外アクセスなどクラッシュするような場合など本当に例外な場合にのみ使います。
そのため、例外はテストなどのデバッグ期間でしか発生しないものでなければなりません。
Exceptions and Errors(Coding Guidelines for Cocoa)

名前空間はない
C++やJavaのように名前空間はありません。NSとか接頭語がついているのもそのためです。

ヘッダーファイルでの2重インクルードの防止は不要
CやC++ではヘッダーファイルの2重インクルードを避けるために#ifdefをヘッダーファイルにつけるのが慣習ですが、Objective-Cでは#importを使えば不要です。


余談ですが、Googleのガイドラインを見るとかなりがっちり決まってたので驚きました。
Objective-Cはフリーダムにかける方だと思うので複数人での開発であれば、Googleのように厳密に決めてやったほうがいいと思います。しかし、性能などとのトレードオフもあるので他のガイドラインをまるパクりではなく、プロジェクトにあったものを選択して採用すべきです。

参考資料
Cording Guidelines for Cocoa
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html

The Objective-C Programming Language
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html

Memory Management Programming Guide


Google Objective-C スタイルガイド(日本語訳)

2011年6月13日月曜日

HPとRIMのタブレット

webOS,BlackBerryと新たなプラットフォームを要したタブレットがいよいよ登場。

HP、PalmのwebOS搭載タブレット「HP TouchPad」を7月に発売http://www.itmedia.co.jp/news/articles/1106/10/news020.html

RIM、タブレット端末「BlackBerry PlayBook」を世界展開、16カ国・地域で発売へhttp://itpro.nikkeibp.co.jp/article/NEWS/20110613/361295/

これでタブレットの役者はほぼ揃いました。
Windowsはかなり遅れをとってますね・・

といってもただ出揃っただけで、やはりどれもiPadを照準としてつくっていたのは明らかで
残念ながらiPad2が出てしまった今では、比較すると見劣り感がいなめなく、かなり不利な状況ではないでしょうか。

Objective-Cの性能・フットプリント

Objectiv-CではC++と比べて、開発者が楽になるようにいくつか仕組みが入っています。
それを効果的に使うことによって開発の生産性をあげることが可能ですが、よく知らずにつかっていると、性能を劣化させたり、フットプリントが大きくなり無駄に大きいアプリになってしまう恐れがあります。

このような問題が発生しやすいポイントについて記載します。

プロパティ
Objective-Cでは、アクセッサ、いわゆるただ値をインスタンス変数に読み書きするだけのGet/Setメソッドを開発者が記載する手間を省くのを手助けしてくれます。
それがプロパティです。

・プロパティを使わない場合

@interface ClassA : NSObject {
NSArray* array;
}
- (NSArray*)getArray;
- (void)setArray:(NSArray*)inArray;
@end
@implementation ClassA
- (NSArray*)getArray
{
return array;
}
- (void)setArray:(NSArray*)inArray
{
if ( array != inArray ) {
[array release];
array = [inArray retain]; }
}
@end

・プロパティを使った場合

@interface ClassA : NSObject {
    NSArray* array;
}
@property (nonatomic, retain) NSArray* array;
@end
@implementation ClassA
@synthesize array;
@end

という風に見れば一目ですが、プロパティのほうが書くコーディングの量が全然違ってきますし、retainとかcopyとか指定すればそのとおりに実現してくれるので大変楽なので使ったほうがよいです。

しかし、プログラムの書く量が少ないからといって、プログラム自体(実行ファイル)が小さくなるわけではありません
プロパティを使ったとしても実際にコンパイルすると、プロパティを使わない場合と同等の量の実行ファイルが生成されることになります。

逆にGet/Setの片方しか使わない場合は、プロパティを使わないほうが小さいプログラムとなります。
ですので、なんでもかんでもインスタンス変数をプロパティにしてしまうのはプログラムサイズとしてはよくありません。

また、性能面でも少し影響がでる場合があります。

自分のクラスのインスタンス変数にアクセスする場合、以下の2パターンあります。
(arrayはプロパティとして宣言されてる場合です)

・①

array = [NSArray new];
・②

self.array=[NSArray new];


①と②は、C++をやっていた人にはこれは同じに見えますが、これは別物です

①は単純な代入ですが、②はアクセッサをつかって代入をしています。
プロパティでassignだったら結果は同じですが、retainなどをしていると②のほうはretainされます。

ですので、retainするために、②を使うのは正しいですが、単に代入するのに②を使うと①に比べて関数を呼び出す分だけオーバーヘッドが生じます。

ひとつひとつではたいしたオーバーヘッドではありませんが、大きいプログラムとなると小さな積み重ねも大きくなることもあるので、そのことを理解しておく必要はあると思います。

Autorelease
つぎにAutoreleaseです。
Autoreleaseはガベージコレクション(GC)みたいで楽なイメージがするかもしれませんが、もちろんGCとは全然違います。

最も気にすべき違いはメモリを開放するタイミングです。

GCは実装によって様々あるので、特に触れませんが、Objective-CのAutoreleaseがメモリを開放するタイミングは、GUIからのイベントを受け取る実行ループでAutoreleaseプールがあるので、一回の実行ループ毎にAutoreleaseプールは開放されます。

つまりひとつのイベント処理が止まるまでAutoreleaseしたメモリは消されずにひたすら溜まりっぱなしということになります。
ですので、ひとつのイベント処理でメモリを大量に使うようなプログラムでAutoreleaseばっかり使っているとメモリ不足になる危険性があります。

これを回避するにはAutoreleaseの使用をできるだけ避けてreleaseで開放するか、独自のAutoreleaseプールを作成して、それを適宜開放するかです。

Autoreleaseは使わざるを得ない場合もあり、完全に回避することは難しいので、両方使うのが望ましいと思います。

-----------------------------------------------------------------------------------------------------------
嘘とか間違いなど指摘していただけると幸いです。

Objective-Cの理解に役立つ本

Objective-Cの言語の本はこれしか読んだことがないので・・。