小学1年生でも7月中に夏休みの宿題を終わらせる方法(続)

小学1年生でもわかる7月中に夏休みの宿題を終わらせる方法 | Moonmile Solutions Blog

の続き。

夏休み帳ですが、昨日学童に行った時に【全て】終わらせたそうです。
計画通りというか、計画倒れというか、計画無視というか、まぁ、早くやる分にはそれでOK。

さて、手早く済ませたのですが、実はいくつか残りがあります。

・答えが間違っているもの
・わからないので飛ばしたもの

IT の PG 工程で言えば、

・コーディングしたけど、間違っている(不具合の混入)
・コーディング抜け。

ですね。

■コーディング抜けの対処

これをどのように対処するかというと、「分からないの飛ばした」に関しては、ざっと見ると分かります。
答えが空欄になっていますからね。
PG で言えば、設計に書かれているけど、コーディングされていない、という【抜け】の問題です。
夏休み帳の場合は、あらかじめ答えを書く空欄が用意してあるので、ざっと見ただけで分かります。
なので、PG 工程の場合も似たようなことをすれば

・あらかじめ、クラス設計などでメソッドだけを用意しておく。
・あらかじめ、xUnit を作って、仮メソッドだけを用意しておく。

という方法です。箱だけ用意しておくと抜けがわかります。

前提条件として、コーディングの前にざっとですがクラス設計をしないといけません。
また、コーディング前のクラス設計が間違っていると修正が困難になります。

なのでオブジェクト指向設計なりデータ指向設計なりの構造設計をしておきましょうという話です。

■コーディングミスの対処

夏休み帳の答えが間違っている場合は、ざっと見ただけでは分かりません。
答えあわせをしないと駄目ですよね。

これがいわゆる単体試験の工程です。
答え合わせは、逐次やってもよいし、あとでまとめてやっても良いわけで、

・あとでまとめてやるのが、ウォーターフォールの従来型の工程
・逐次テストするのが、xUnit を使った工程

ってことです。

■クリア条件があるもの

さて、実はもうひとつの試験方法があります。

先の逐次テストの場合は、ホワイトボックス的に、期待値が明確である時に使います。
夏休み帳のような、答えが明確になっているものは、このタイプです。

もうひとつ、絵日記のような答えが明確ではないものがありますね。
絵日記の場合は、「ある程度の絵と文書が入っていること」がクリア条件になるのです。
これが、丁度、xUnit のブラックボックステストになります。

とある期待値をクリアしているかどうかということで、性能試験や受け入れ試験に使います。
受け入れ試験の場合は、実際のコードを使って xUnit でエミュレートをします。この場合、MVC モデルなどを利用して xUnit 使いやすくしておくことがベストですね。View/GUI 部分は手作業になることが多いので、xUnit に向きません。

絵日記の場合はどうでしょうか。見た感じ、できているかなぁ、というのもアリですが、もう少し期待値を決定してみると、

・絵の部分で、50% 以上、色が塗ってあること。
・日付が書いてあること。
・天気が書いてあること。
・文章が、50% 以上書いてあること。

のような感じで、View/GUI から切り離してテストが可能です。
まぁ、そんな厳密ではないけれど、こんな風なクリア基準があるはずです。

カテゴリー: プロジェクト管理 | 小学1年生でも7月中に夏休みの宿題を終わらせる方法(続) はコメントを受け付けていません

小学1年生でもわかる7月中に夏休みの宿題を終わらせる方法

「小学1年生」と銘打っているのは、うちの娘が小1になったからなんです。
最近の小学校は、8月末までの夏休みではないそうで、中途半端に8月20日頃(正確な日付は忘れました)から2学期が始まります。

まぁ、それはさておき。

夏休みの宿題を8月末まで引っ張らないためには、【計画を立てて】そして【計画通り】に実行する、というのが定番ですが、プロジェクトの考え方で言うと、全く駄目です。絶対に遅れがでます。なので計画通りに終わることはありません(計画に忠実な、妙に厳しいマネージャ=親がいれば別ですけど)。

そんな訳で、アジャイルに、と言いますか、TOC で、と言いますか、私が小学生の頃にやっていた方法を公開します。
# 基本的な方法は、今でも変わっていなかったりして。

以下が、今回の計画の手順。

1.夏休みの宿題が全体で、どれだけなのか確認する。
 → 朝顔の観察が3枚
 → 絵日記が2枚
 → 夏休み帳が32ページ
 
2.7月中に終わらせるものをピックアップする。
 → 朝顔の観察で、2枚は7月中、1枚は8月
 → 絵日記は、1枚は7月中、1枚は8月
 → 夏休み帳は、7月中に
 
3.夏休み帳を7月に終わらせるために、毎日何ページやれば良いか計算する。
 → 娘自身が数えたところ、毎日3ページやれば、8月1日に終わるそうです。
 → 土日もやるらしいが、黙っておく(後で、土曜日に聞いてみます)
 
4.夏休み帳を毎日、【最低限】3ページやる。
 → 気が向いたら、3ページ以上やってもよい。
 

こんな感じです。

このスケジューリングのミソは、

・【最低限】3ページずつやる。
・気が向いたら、3ページ以上やってもよい。

の組み合わせです。

ひとつ目は、最低ラインを決めておいて、最低限スケジュールが守れるようにします。
ふたつ目は、余力があればタスクを先に進めるということです。

現状の IT 系のスケジューリングで一番まずいのは(ウォーターフォールでもアジャイルでも)、ひとつ目の縛りを守らないのもそうなのですが、ふたつ目を行うための余裕を持たせないことで、失敗する例が非常に多いのです。
タスクをこなす量は、日々ムラが出るのは仕方がないので、ひとつ目の縛りが多少上下しても構いません。ただし、その上下分を後からフォローできるようなバッファを取ることが大切です。それが、ふたつ目の余力になります。

だから、親のアドバイスとして、良くない例は、子供が更に夏休み帳をやろうとしているときに

「もう、3ページやったから、明日また3ページやろうね」
「既に3ページやったから、また明日にすればいいんじゃない」

とスケジュール通りに運ぼうとするのが間違いで、余力を削ってしまっています。
やる気なりモチベーションなりやれる時間なりがあるときは、

「3ページやったのだから、あとは自由にやっていいよ」
「3ページやったから、後は疲れないようにやっていいよ」

という余力で進めます。

こうすると、夏休み帳を7月中に終わらせる、という【目的】に沿って行動ができるようになります。
最低限、毎日3ページというノルマがあるので、計画通りにも終わります。

【目的】を忘れて【計画】に沿わせようとすると失敗しますよ、という話です。

カテゴリー: プロジェクト管理 | 7件のコメント

2つの MPMediaPickerController を配置すると片方が真っ黒になる

iPad で mpeg などの動画を表示するためには、MPMediaPickerController を使います。

MPMediaPickerController Class Reference
http://developer.apple.com/library/ios/#documentation/mediaplayer/reference/MPMediaPickerController_ClassReference/Reference/Reference.html

NSString mpegFile = @"douga";
MPMoviePlayerController *movie = 
	[[MPMoviePlayerController alloc] 
		initWithContentURL:
    	[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:mpegFile ofType:@"mp4"]]];

movie.shouldAutoplay = YES; // auto で開始
movie.controlStyle = MPMovieControlStyleNone; // コントローラーを非表示
movie.scalingMode  = MPMovieScalingModeFill; // サイズに合わせる
movie.view.frame = CGRectMake(0,0,300,200);

これを viewDidLoad の時にでも記述します。

で、普通は1枚しか表示しないんですが、電子書籍上、サマリなんかで複数枚表示したいと思った訳です。

↓な感じに。

NSString mpegFile = @"douga";
for ( int x=0; x<2; x++ ) {
for ( int y=0; y<2; y++ ) {
MPMoviePlayerController *movie = 
	[[MPMoviePlayerController alloc] 
		initWithContentURL:
    	[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:mpegFile ofType:@&quot;mp4&quot;]]];

movie.shouldAutoplay = YES; // auto で開始
movie.controlStyle = MPMovieControlStyleNone; // コントローラーを非表示
movie.scalingMode  = MPMovieScalingModeFill; // サイズに合わせる
movie.view.frame = CGRectMake(x*300,y*200,300,200);
}}

なのですが、何故か最後の追加した movie だけが表示されて、後は真っ暗なのです。
この例だと、同じファイルを表示させていますが、実際は別々のファイル名を指定します。

理由はよく分からないのですが、英語のサイトでも multi MPMoviePlayerController では動かん、ってことなので仕様なんですかね。ちょっと対策を思案中。

カテゴリー: iPad | 1件のコメント

ankhsvn の sharpsvn を使ってコマンドライン版を作ってみる

Visual Studio では VSS を使えッ!!! ってのが定番ですが、「それってお高いんでしょう?」ってな具合に SubVersion を使うことが多々あります(最近は git なのか?)

ankhsvn: Subversion Support for Visual Studio
http://ankhsvn.open.collab.net/

これをインストールすると Visual Studio 上から VSS ライクに SubVersion のリポジトリを操作できるので便利です。

が、checkout をするのに、いちいち Visual Studio を立ち上げないと駄目ってのが面倒なのです。それで、別途

tortoisesvn.tigris.org
http://tortoisesvn.tigris.org/

なものを入れて、エクスプローラから直接操作できるようにするのが普通なのですが、これって 、

・SVN のクライアントが二重に入っているのが変
・コマンドラインで一発で checkout するほうが、バッチ処理的に便利

なわけです。

で、最近気づいたのですが、ankhsvn をインストールしたフォルダには SharpSvn.dll なんていう、それらしいファイルがあるじゃないですか。

探してみれば、

sharpsvn: Samples
http://sharpsvn.open.collab.net/servlets/ProjectProcess?documentContainer=c4__Samples&view

というサンプルがあったりして。

試しに下記のように、書いただけで checout と update が簡単にできます。

imports SharpSvn

Module Module1
	Sub Main()
		Dim addr As New Uri("svn://...")
		Dim outdir As String = Directory.GetCurrentDirectory
		Dim client As New SvnClient
		AddHandler client.Notify, AddressOf prog
		if Directory.Exists(".svn") = false then
			Console.WirteLine("svn checkout")
			client.CheckOut( addr, outdir )
		else
			Console.WirteLine("svn update")
			client.CheckOut( outdir )
		end if
	End Sub
	
	public sub prog( byval sender as object, e as SharpSvn.SvnNotifyEventArgs )
		Console.WriteLine(e.Path)
	end sub
	
End Module
カテゴリー: 開発 | 1件のコメント

Windows Azure SDK 1.4 をインストール

Windows Azure の執筆を初めて気づいたのですが、Windows Azure の諸々の設定関係、初期の頃のベータ版やら現在の Windows Azure Platform の画面が以前とは違っているやら、という訳で、それなりに苦労しました。

多分、以下な本家本元

Windows Azure Platform デベロッパーセンター: 開発 | MSDN
http://msdn.microsoft.com/ja-jp/windowsazure/default

から辿ればよいのでしょうが、なにかと便利なブログが google から引っ掛かるので、それをついつい見てしまいます。

で、開発者としては Visual Studio 2010 に Tools を入れるということで、

Windows Azure Tools for Microsoft Visual Studio 1.4
http://www.microsoft.com/downloads/ja-jp/details.aspx?FamilyID=7a1089b6-4050-4307-86c4-9dadaa5ed018&displayLang=ja

をインストールすることになっていますが、実は、Windows Azure Platform から「Install the Windows Azure Tools」をクリックすると、WebPI(Web Platform Installer)経由で IIS の設定もろもろインストールしてくれます。

↓なところで、Get Tools & SDK
Windows Azure SDK and Tools | Windows Azure Platform
http://www.microsoft.com/windowsazure/sdk/

カテゴリー: 開発, Azure | Windows Azure SDK 1.4 をインストール はコメントを受け付けていません

wordpress と iPhone/iPad の連携を考える

ふと、XMLRPC が使えるのだから、iPad から WordPress のブログを更新してもいいんじゃ?

0から始めるiPhoneからのWordPress更新術 | Feelingplace
http://www.feelingplace.com/wp_update_from_iphone/

と思った訳ですが(そんなわけで、Textforce が手元の iPhone に入っていたりします)、一度もこのブログに対して更新したことはありません。つーか、プログラムコードを載せるのが目的(だけでもないけど)だから、iPad でコーディングをするよりも、PC を使ったほうが断然楽なんですよね。なので、Visual Studio でコーディングして、エディタ(QX エディタとか sakura エディタ)で適当なタグを入れて、後は自作のスクリプトで更新処理をするか、ブラウザ上で書き込んでしまう、というのが私のスタイル。

が、専用アプリでブログを更新するのは、極めて便利なパターンがあるわけで、汎用的な場合は PC で書いてもいいんですが、

・写真だけを up したい写真ブログ
・食べ物の感想だけを up したい、写真&感想ブログ
・毎日の定型フォーマットを残しておきたい、定型のブログ

な風に「ブログ」でなくても、定型処理して up する場合は、それ専用のアプリあるいは入力フォーマットがあったほうが便利なわけです(業務的な視点で言えば、営業報告書みたいなものですね)。

この手のコンセプトは、いわゆる社内の業務アプリケーションにあるパターンと同じで、

・入力項目が限られている(あるいは必須項目がある)
・定型業務を高速に入力できる(作業能率をあげる)
・誰が入力しても(初心者が入力しても)同じフォーマットで入れられる(属人性が低い)
・データベース化して、何かと連携させる(フリーフォーマットではない)

のようなカスタムメイドっぽい入力方法を提供すればよいのです。

と、ここまで書いていて、昔 Workpad(palm) でメモを書いていた頃、そして iPad の標準的なメモ帳を使ってメモを書いてる自分を振り返ると、タイトルを1行目に書いて、以下本文を書くというフォーマットでも実は十分なのです。

この行がタイトルになる
以下は、本文
...
つづく

ただ、これだとメモ帳で見たときに見づらいことが多いので、1行空けています。

この行がタイトルになる
		← 空行を入れる
以下は、本文
...
つづく

さて、ここでカテゴリを加えるときにどうするのかというと、所謂 mail フォーマット(HTTPプロトコルのフォーマット)風なものを使います。

Title: この行がタイトルになる
Category: ブログ
		← 空行を入れる
以下は、本文
...
つづく

「種別」+「コロン」+「値」という形式です。
こうしておくと、perl やら ruby やらで整形するときに非常に便利なのです。

が、PC のように専用のキーボードがある場合、このような【冗長な】記号を使ってもいいのですが、palm や iPhone の場合には、この記号をタイピングするのが面倒だったりします。なので、キータイピングが遅い(あるいはキー入力を得意としない)端末を対象にする場合は、折衷案として、あらかじめ「種別」の部分をいれたテンプレートを作っておきます。

Title: 
Category: 
		← 空行が入っている

これを、テキストボックスやリストを貼り付けて選択させてもよいのですが、本文に注力する場合には【視覚的に】冗長なんですよね。なので、ノーマルなテキストにある程度の記号が入っているほうが思考を妨げません。
逆に言えば、写真ブログのように「写真」が中心な場合には、カテゴリはリストから選択、という方法をとったほうが楽です。というのも写真は
「文章」ではないので、「文章でないもの=写真」と「文章=カテゴリの入力など」、を行き来するよりも、「文章でないもの=写真」と「文章でないもの=カテゴリの選択」としたほうが、思考を妨げません。

じゃあ、カテゴリなんかはいちいちタイピングしないといけないのか?というと慣れていない iPhone のソフトウェアキーボードを使うと面倒ですよね。私はいまだにフリックのスピードが遅いので、ちょっと困りものです。

なので、アプリのほうが一工夫して、

Title: 
Category: .ブログ

のようにピリオドを打つと、候補が展開される、というようなインテリセンスな機能があると良いのかなぁと。まぁ、「ブ」を打った時点で「ブログ」まで出してくれてもいいのですが、カテゴリ全体を表示させたい場合は、なんらかのプレフィックスがあったほうがいいのです。

あるいは、「Category: 」のところで左にスライドをするとカテゴリのリストが現れるとか、タッチをすると「>」記号が現れて選択を示すとか。iPhone のナビゲーションはそういうスタイルになっているのでそれに合わせるのも良いですね。

とかなんとか、考えてみたという話です。

カテゴリー: ブログ, iPad | 2件のコメント

clang+llvm で objc を DataTable っぽく扱う

うれしげに、@property で DataRow を作って見た例。
もうちょっと整理しないと。

/*
clang -o main4 main4.m -I /llvm/include -I /GNUstep/GNUstep/System/Library/Headers -L c:/GNUstep/GNUstep/System/Library/Libraries -lobjc -lgnustep-base -fconstant-string-class=NSConstantString -Wno-format-security
*/
#import <stdio.h>
#import <Foundation/Foundation.h>
#import <Foundation/NSObject.h>

@interface Person : NSMutableDictionary
{
	@private
	int _id ;
	NSString *_name;
	int _age ;
}
@property (nonatomic) int id ;
@property (nonatomic,retain) NSString *name;
@property (nonatomic) int age ;
@end

@implementation Person
@synthesize id = _id ;
@synthesize name = _name ;
@synthesize age = _age ;
- (void)print 
{
	NSLog(@&quot;%d %@(%d)&quot;, _id, _name, _age );
}
- (Person*)initWithId:(int)id Name:(NSString*)name Age:(int)age 
{
	_id = id;
	_name = name;
	_age = age;
	
	return self;
}
@end

@interface Persons : NSObject
{
	@private 
	NSMutableArray *_rows ;
}
@property (nonatomic,retain) NSMutableArray *rows ;
@end

@implementation Persons
@synthesize rows = _rows;

- (id)init
{
	[super init];
	_rows = [[NSMutableArray alloc] init];
	return self;
}
- (void)print 
{
	for ( int i=0; i< [_rows count]; i++ ) {
		Person *p = [_rows objectAtIndex:i];
		[p print];
	}
}

@end



int _main(int argc, char *argv[])
{
	Person *masuda = [[Person alloc] initWithId:1 Name:@&quot;masuda&quot; Age:40];
	Person *yamada = [[Person alloc] initWithId:2 Name:@&quot;yamada&quot; Age:50];
	Person *tanaka = [[Person alloc] initWithId:3 Name:@&quot;tanaka&quot; Age:20];
	Persons *persons = [[Persons alloc] init];
	[persons.rows addObject:masuda];
	[persons.rows addObject:yamada];
	[persons.rows addObject:tanaka];
	[persons print];
	
	return 0;
}

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int retVal = _main(argc, argv);
    [pool release];
    return retVal;
}



カテゴリー: 開発, Objective-C | clang+llvm で objc を DataTable っぽく扱う はコメントを受け付けていません

コードで学ぶ ASP.NET MVC アプリケーション開発入門 全10回

コードで学ぶ ASP.NET MVC アプリケーション開発入門
http://msdn.microsoft.com/ja-jp/asp.net/gg490787

が全10回で連載終了しましたッ!!! ってことで、まとめリンクです。
後で、固定ページにでも移しておきます。

はじめに「MVC パターン」とは何か
本連載では、日経 BP 社から発売された「ひと目でわかる ASP.NET MVC アプリケーション開発入門」をもとにして、執筆時に気づいたことや紙面の都合で書ききれなかった技術を紹介します。

第 1 回 ASP.NET MVC 概要
連載第 1 回は、ASP.NET MVC 2 の具体的な開発の全体像をみていきましょう。

第 2 回 アクション メソッドについて
連載の第 2 回目は、ASP.NET 4 で導入された「URL ルーティング」と、ASP.NET MVC 2 で必ず理解が必要な「アクション メソッド」についてお話ししましょう。

第 3 回 ViewDataDictionary を利用する
連載の第 3 回目は、コントローラー (Controller) からビュー (View) に直接データを渡すための ViewData プロパティ (ViewDataDictionary クラス) についてお話していきましょう。

第 4 回 Entitiy Frameworkを利用する
連載の第 4 回目は、データベースを扱うフレームワーク「ADO.NET Entity Framework」を使ってサンプルを動かす方法についてお話していきましょう。

第 5 回 HTML ヘルパー メソッドを使用する
連載の第 5 回は、ASP.NET MVC アプリケーションのビューで使われる HTML ヘルパー メソッドについてお話していきます。

第 6 回 Site.Master の編集とページ デザイン
連載の第 6 回は、ADO.NET Entity FrameworASP.NET MVC アプリケーションの全体的なデザインを担っているマスター ページに関して解説をしていきます。

第 7 回 JavaScript と jQuery を利用する
連載の第 7 回は、Web アプリケーションでは今や必須の技術となった JavaScript との組み合わせについて解説していきます。ASP.NET MVC でも JavaScript は重要な技術です。

第 8 回 Action Filter について
連載の第 8 回は、ASP.NET MVC のアクション メソッドを拡張するアクション フィルターについて解説します。アクション フィルターは、メソッドの属性として設定されます。クラスの静的なデータとして設定されるため、クラス内の共通処理を行う場合に使うことができます。

第 9 回 出力キャッシュの利用
Web アプリケーションでは、ご存じのようにクライアント (ブラウザー) と、サーバーの間にネットワークがあり、そのネットワークを通じてデータのやり取りをしています。ブラウザー上でひとつの画面から別の画面に移るたびにサーバーで処理が行われ、データのやり取りが発生しています。出力キャッシュは、このサーバーの処理を軽減するための機能になります。

最終回 コントローラー アクション メソッドの単体テスト
ASP.NET MVC アプリケーションの単体テストを取り上げます。Visual Studio 2010 で ASP.NET MVC アプリケーションのプロジェクトを作ると、最初に「単体テストのプロジェクトの作成」のダイアログが開きます (ASP.NET MVC 3 の場合は、「単体テストのプロジェクトを作成する」のチェック ボックスを ON にします)。

おまけとして、コードレシピへのリンク


カテゴリー: 開発, ASP.NET | コードで学ぶ ASP.NET MVC アプリケーション開発入門 全10回 はコメントを受け付けていません

clang+llvm で objective-c 2.0 をコンパイルする

LLVM-GCC 4.2 Front End Binaries for Mingw32/x86
http://llvm.org/releases/download.html#2.9
KMC Staff Blog:Clang と LLVM を使ってみる。
http://blog.kmckk.com/archives/2435798.html

実は、よく分からんというのが本音ですが、mingw + gnustep の組み合わせだと objective-c の @property がコンパイルできません。

なので、先のリンクから↓の3つをダウンロードしてきて c:\llvm とかに移動

Clang Binaries for Mingw32/x86 (23M)(.sig)
LLVM Binaries for Mingw32/x86 (23M)(.sig)
LLVM-GCC 4.2 Front End Binaries for Mingw32/x86 (26M) (.sig)

別に入っている

GNUstep Windows Installer
http://www.gnustep.org/experience/Windows.html

の include を設定すると、@property がうまくコンパイルできます。かつ、うまく動きます。

#import <stdio.h>
#import <Foundation/Foundation.h>
#import <Foundation/NSObject.h>

@interface Hello: NSObject
{
	@private
	NSString *_msg ;
}
@property (nonatomic,retain) NSString *msg;
@end

@implementation Hello
@synthesize msg = _msg ;

- (void)print
{
	// NSLog( _msg );
	printf(&quot;%s\n&quot;, [_msg cString]);
}
- (void)dealloc
{
	NSLog( @&quot;in dealloc&quot; );
	[super dealloc];
}
@end


int main(int argc, char *argv[])
{
	puts(&quot;hello obj-c world.&quot;);
	Hello *hello = [[Hello alloc] init];
	hello.msg = @&quot;hello objc world.&quot;;
	[hello print];
	[hello release];

	return 0;
}

こんな風に @property を使ったコードを書いておきます。

そして、最初は clang だけでコンパイルしてみると。

clang -o main3 main3.m -I /llvm/include -I /GNUstep/GNUstep/System/Library/Headers -L c:/GNUstep/GNUstep/System/Library/Libraries -lobjc -lgnustep-base -fconstant-string-class=NSConstantString

のようにコンパイルして実行すると、次のようにうまく動きます。

C:\work\alice\objc>main3
hello obj-c world.
2011-07-05 18:12:32.113 main3[2400] in dealloc

~~~

試しに vm 上で動かしてみようと

clang -emit-llvm -S main3.m -I /llvm/include -I /GNUstep/GNUstep/System/Library/Headers
llvm-as main3.s
lli main3.s.bc

な風にコンパイルしましたが、

C:\work\alice\objc>lli main3.s.bc
LLVM ERROR: Program used external function '__objc_exec_class' which could not b
e resolved!
Stack dump:
0.      Program arguments: lli main3.s.bc
1.      Running pass 'X86 Machine Code Emitter' on function '@.objc_load_functio
n'

な風に実行エラーになりますね。objc のランタイムを clang でコンパイルして配置するんでしょうが。

カテゴリー: 開発, Objective-C | 2件のコメント

objective-c の autorelease の動き

C# のガベージコレクションと同じなのかなぁ、と思ったけど、動き的には c++ のスマートポインタに近いのかな。
autorelease を指定すると、NSAutoreleasePool のオブジェクトに溜め込まれるようです。ここで、間違って release してしまうと落ちてしまう(core dump)ので、alloc と release の対応は、malloc/free, new/delete 並に厳しいコーディングをしないと駄目ですね。
一律、autorelease を使って release を使わないで記述するか、autorelease を使わずに release 自体をまめにコーディングしていくか悩むところ。

UIImage のように大きめなメモリを取得するものは、autorelease にするとメモリを占有してしまうので、release をするってのが適当ですね。

/*
export INCLUDE=/GNUstep/System/Library/Headers
export LIB=/GNUstep/System/Library/Libraries
export CFLAGS='-fconstant-string-class=NSConstantString  -enable-auto-import'

gcc -o main main.m -lobjc -lgnustep-base -I $INCLUDE -L $LIB $CFLAGS
*/
#import <stdio.h>
#import <Foundation/Foundation.h>
#import <Foundation/NSObject.h>

@interface Hello: NSObject
{
	@private
	NSString *_msg ;
}
@end

@implementation Hello
- (void)setMessage:(NSString*)msg 
{
	_msg = msg;
}
- (void)print
{
	// NSLog( _msg );
	printf(&quot;%s\n&quot;, [_msg cString]);
}
- (void)dealloc
{
	NSLog( @&quot;in dealloc&quot; );
	[super dealloc];
}
@end

int _main(int argc, char *argv[])
{
	puts(&quot;hello obj-c world.&quot;);

	// autorelease を使った場合
	Hello *hello = [[[Hello alloc] init] autorelease];
	[hello setMessage:@&quot;hello objective-c in hello class&quot;];
	[hello print];
	
	// autorelease を使わない場合
	Hello *hello2 = [[Hello alloc] init];
	[hello2 setMessage:@&quot;hello objective-c no autorelease&quot;];
	[hello2 print];
	[hello2 release];
	
	return 0;
}

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int retVal = _main(argc, argv);
	NSLog(@&quot;before pool release&quot;);
    [pool release];	// ここで一気に解放される
	NSLog(@&quot;after pool release&quot;);
    return retVal;
}

実行結果

$ main
hello obj-c world.
hello objective-c in hello class
hello objective-c no autorelease
2011-07-05 15:46:23.484 main[4124] in dealloc
2011-07-05 15:46:23.545 main[4124] before pool release
2011-07-05 15:46:23.545 main[4124] in dealloc
2011-07-05 15:46:23.545 main[4124] after pool release
カテゴリー: 開発, Objective-C | objective-c の autorelease の動き はコメントを受け付けていません