2010年5月28日金曜日

Google App Engine for Java[実践]クラウドシステム構築」正誤表 第3章

p.86 リスト3.4.1

package mysite.server;

import java.io.IOException;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class LogFilterImpl implements Filter {

    private FilterConfig filterConfig;

    private static final Logger LOG =
            Logger.getLogger(LogFilterImpl.class.getName());

    @Override
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain filterChain)
            throws IOException, ServletException {
        LOG.info("Log filter processed a " +
                 filterConfig.getInitParameter("logType") +
                 " request");
        filterChain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    @Override
    public void destroy() {
        // no-op
    }
}

2010年5月12日水曜日

NSArrayとNSDictionaryのオーナーシップ

Objective-C 2.0ではガベージコレクションが導入されて、メモリ管理がだいぶシンプルになりましたが、iPhone開発ではその恩恵に預かれませんので、色々と気を使います。

NSArrayに要素を追加した時、NSArrayはその要素オブジェクトにretainメッセージを送ってオーナーシップを獲得します。NSArrayが解放された場合、格納されているオブジェクトすべてにreleaseメッセージが送られます。また、格納した要素をNSArrayから削除した場合、その要素にreleaseメッセージが送られます。

なので、こういう書き方をするのはちょいとよろしくありません。

NSArray *array = [[NSArray alloc] initWithObjects:
                     [[Foo alloc] init], [[Bar alloc] init],nil];
// なんらかの処理
[array release];

FooとBarをallocしてinitした時点で、このコードが書かれているオブジェクトがFooとBarそれぞれのオーナーになります。その後、array に追加しているので、array もこの2つの要素のオーナーシップを持ちます。

array を release する事で、Foo と Bar にもreleaseメッセージが送信され、retainCount が減るのですが、コードが書かれてるオブジェクトがまだオーナーシップを握っているため、破棄されません。このコードだと破棄しようもない。困った。

なので、律儀にこう書くのが吉。

Foo *foo = [[Foo alloc] init];
Bar *bar = [[Bar alloc] init];
NSArray *array = [[NSArray alloc] initWithObjects: foo, bar, nil];
[foo release];
[bar release];
// なんらかの処理
[array release];

これじゃどんくさい、という人はautoreleaseにまかせてしまうとか。

NSArray *array = [[NSArray alloc] initWithObjects:
                     [[[Foo alloc] init]autorelease],  [[[Bar alloc] init]autorelease], nil];
// なんらかの処理
[array release];

iPhone環境はautoreleaseは結構まめにやってくれる事がこないだ判ったので、これで安心でしょう。

NSDictionaryの場合、こちらもNSArrayとほぼ同様なのですが、値はそのまま参照してretainメッセージを送りますが、キーはオブジェクトをコピーして保持するそうです。

私はどんくさい方が好みです。実生活ではぐうたらであまり掃除は得意でないんですが。

2010年5月7日金曜日

Java入門サンプル(1)

  • 注意
    • このエントリは実験中のJava入門教材のサンプルです
    • GAE の調子が悪かったりQuotaを超えてたりするとデモがうまく動かないかもしれません
    • 技術背景等はGooseあたりを参照してください

Hello, world!

まずは簡単なプログラムを作成してみましょう。Hello.javaという名前のファイルを作成して次の内容を書き込んでください。

public class Hello {

    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}

このプログラムを実行するには、コマンドラインで次のように指定します。

cd (ファイルを作成したフォルダ)
javac Hello.java
java -cp . Hello

すると、「System.out.println("Hello, world!");」のところに書いた「Hello, world!」という文字列が画面に表示されたと思います。

Hello, world!

Javaのプログラムは次のような構造で書きます。

public class (ファイルの名前) {

    public static void main(String[] args) {
        (命令)
    }
}

今回は(命令)の部分に、「System.out.println(...);」という「標準出力に文字列を表示する命令」を書きました。 Javaの文字列は " (ダブルクウォーテーション)で囲んで「"Hello, world!"」のように指定します。

練習

2行以上の出力

(命令)の部分には複数行の命令を書くこともできます。

public class (ファイルの名前) {

    public static void main(String[] args) {
        (命令)
    }
}

Hello2.javaという名前のファイルを作成して次の内容を書き込んでください。

public class Hello2 {

    public static void main(String[] args) {
        System.out.println("こんにちは");
        System.out.println("世界");
    }
}

先ほどと同じように実行してみましょう。

cd (ファイルを作成したフォルダ)
javac Hello2.java
java -cp . Hello2

今回は「こんにちは」と「世界」がそれぞれの行に表示されたと思います。

こんにちは
世界

このように、(命令)の部分には連続してJavaの命令を書くことができます。 今回は「System.out.println(...);」という「標準出力に文字列を表示する命令」を2回使って、2行にわたって文字列を表示しました。

System.out.println("こんにちは");
System.out.println("世界");

また、命令は上から書いた順に実行されます。 1行目は「こんにちは」という文字列を表示して、2行目は「世界」という文字列を表示するプログラムですので、その順番で表示されたと思います。

練習

おまけ

2010年5月6日木曜日

XCode上でXIBファイルを作る時の注意点

大した話でもないんですが。

UIViewControllerのサブクラスのソースファイルをXCode上で新規作成する際に、XIBファイルも同時に作成するオプションがあります。

このオプションを使って出来たXIBファイルは、ソースファイルと同じ場所に出来ます。これではなんなので、XCode上でResourcesへXIBファイルを移動したくなりまして、ドラッグ&ドロップでResources直下へ落としてやったとします。

果たしてそれはXCodeの「グループとファイル」上では上手くいくのですが、ファイルシステム上の位置は変わりません。Classesの中に居っぱなしです。

また、XIBファイルのみを新規作成する場合、「グループとファイル」上のResourcesを選択してその中に作るかと思いますが、そうするとファイルシステム上だとプロジェクトルートにXIBファイルが作成されます。

XCodeの「グループとファイル」ペイン上ではちゃんと仕分けされているので問題はないのですが、どうも気持ち悪いですし、Finderで確認してみようかなという局面の時に要らぬ混乱を来す恐れがあります。

ローカライズなど始めた場合、そこここにxxxx.lprojが出来たりしてどうも落ち着きません。

要は「グループとファイル」上でのドラッグ&ドロップによるファイル移動時にファイルシステムでの移動も可能にする方法があればよいのですが、済みません、見つかってないです。

XCodeのプロジェクトはIDE上で整理出来てればOKだから、ファイルシステム上は野放図でいいよねというポリシーなんでしょうか。