当前位置: 编程技术>移动开发
本页文章导读:
▪软键盘默许输入模式是数字模式 软键盘默认输入模式是数字模式
EditText et = (EditText) findViewById(R.id.et); et.setInputType(InputType.TYPE_CLASS_NUMBER);
1 楼
furlxy
2010-11-30
这代码看着真亲切,看了半天才缓过劲.........
▪ Cocoaのメモリ治理(3) Cocoaのメモリ管理(3)
保持と解除という方法は、理屈は分かるし簡単そうに見えます。しかし、実際にやってみると意外と難しいことがわかります。そこでCocoaでは少し楽をするための.........
▪ [Java江湖]Java的支解之争权夺利 [Java江湖]Java的分裂之争权夺利
Java自出生以后,Sun(现在是Oracle)就竭力维护Java防止分裂,但是Java分裂在不断的发生着。几个有名的Java分裂如下
MicroSoft对Java的分裂
:这个分裂出现在Java的幼.........
[1]软键盘默许输入模式是数字模式
来源: 互联网 发布时间: 2014-02-18
软键盘默认输入模式是数字模式
EditText et = (EditText) findViewById(R.id.et);
et.setInputType(InputType.TYPE_CLASS_NUMBER);
EditText et = (EditText) findViewById(R.id.et);
et.setInputType(InputType.TYPE_CLASS_NUMBER);
1 楼
furlxy
2010-11-30
这代码看着真亲切,看了半天才缓过劲来,这是iphone板块啊
[2] Cocoaのメモリ治理(3)
来源: 互联网 发布时间: 2014-02-18
Cocoaのメモリ管理(3)
保持と解除という方法は、理屈は分かるし簡単そうに見えます。しかし、実際にやってみると意外と難しいことがわかります。そこでCocoaでは少し楽をするための仕組みを導入しています。簡単に言えば、とりあえずなんでも入れておけるごみ袋を用意して、不要になった時点でごみ袋ごと捨てちゃうという方法です。このごみ袋にあたるのが、NSAutoreleasePoolというクラスです。
Application KitにおけるNSAutoreleasePool
さて、Cocoaの重要なフレームワークの一つであるApplication Kitの話から始めたいと思います。Application Kitは、主にGUIを持つアプリケーションを作成するためのフレームワークです。このフレームワークを利用して作ったアプリケーション(つまり、ぶっちゃけた話、ProjectBuilderとInterfaceBuilderを使って作られたNSApplicationを利用するアプリケーション) には、デフォルトで一つNSAutoreleasePoolオブジェクトが生成されています。さらに、NSApplicationが提供するイベントループ内でも、NSAutoreleasePoolオブジェクトが生成され、ループが一回転するごとに解放され、新しいNSAutoreleasePoolオブジェクトを生成します。つまり、NSAutoreleasePoolそのものを知らなくてもとりあえず使える仕組みが提供されているわけです。このごみ袋にオブジェクトを入れる方法が、NSObjectに用意されているautoreleaseメソッドです。Foundation KitとApplication Kitが提供するクラスは、基本的にNSAutoreleasePoolがある環境での動作を想定しています。
- (id)autorelease
Application Kitに準拠したプログラムの場合、任意のオブジェクトにautoreleaseを送っておくと、このオブジェクトはデフォルトの NSAutoreleasePoolオブジェクトに登録されます。そして、このプログラムが終了する直前にデフォルトの NSAutoreleasePoolオブジェクトとともに、登録されたオブジェクトがすべて解放されます。つまりautoreleaseは、retain & releaseの仕組みを使わないで、楽々とメモリ管理を行う仕組みなのです。
- (void)methodA
{
id obj = [[Foo alloc] init];
// objとして参照されているオブジェクトをNSAutoreleasePoolに登録する。
[obj autorelease];
// このメソッドを抜けると、変数objによる参照はなくなるが、
// 割り当てられたメモリは、イベントループのNSAutoreleasePoolが
// 解放される時に解放される。
}
NSAutoreleasePoolの特徴
ApplicationKitが提供するNSAutoreleasePoolを使いこなすにあたって、いくつかの注意すべき特徴があります。
* デフォルトのNSAutoreleasePoolは、プログラムの最後に(つまり、メインスレッドの末端で)解放されるので、基本的にこれに登録されたオブジェクトに割り当てられたメモリはプログラムの最後まで解放されない。
* イベントループ内で毎回生成されるNSAutoreleasePoolは、ループが一回転するごとに解放されるので、基本的にこれに登録されたオブジェクトに割り当てられたメモリはイベント処理が終わると解放される。
* autoreleaseされたオブジェクトが、基本的にそのオブジェクトが登録されたNSAutoreleasePoolがreleaseされるまで解放されないということは、逆に言えば、NSAutoreleasePoolが生きている間は、オブジェクトの生存が保障されるということを意味している。
* ただし、releaseメソッドを送ることで、このようなオブジェクトでもプログラムの途中で解放することは可能である。(これは、推奨されない方法である。基本的に、同じオブジェクトに対してautoreleaseとreleaseを併用することは混乱の元になるので、止めるべきである。 deallocについてはいわずもがな。オブジェクトのプログラマブルな解放のためには、後述する方法を用いるべきである。)
* 例外発生時には、NSAutoreleasePool(と、登録されたオブジェクト)は解放されるので、メモリリークは起こらない。(どっちにしてもプログラムが終了するので、メモリは解放される。)
* デフォルトのNSAutoreleasePoolだけで動作するようなプログラム場合、参照が切れたオブジェクトは、基本的にメモリリークと同じ状況になる。(あえて言うなら、知った上でのメモリリーク。通常のプログラムではあまり気にする必要がない。)
* NSAutoreleasePoolに登録されているオブジェクトへのアクセス手段はないので、参照の管理には注意が必要である。
自前のNSAutoreleasePoolの利用
さて、長々と引き伸ばしてきた話題に入ろうと思います。まず、Application Kitが用意しているNSAutoreleasePoolだけでは、一度のイベント処理で大量にオブジェクトを生成するような処理に対応するのが難しい場合があります。また、そもそもApplication Kitを利用しないプログラム(たとえば、コマンドラインで動作するツールなど)は、この仕組みが提供されていないわけです。そこで、自前の NSAutoreleasePoolを作成して利用する意味が出てくるのです。ここであれこれいうより、まずはサンプルコードで説明しましょう。以下のコード内のobj2を見てわかるように、実はautoreleaseメソッドを呼び出すと、スレッド内で一番最近作られた NSAutoreleasePoolにオブジェクトが登録されます。つまり、テンポラリなオブジェクトは、このように自前の NSAutoreleasePoolオブジェクトを適宜用意してやれば、任意の時点でまとめて解放できるのです。
- (void)methodA
{
id obj1;
id obj2;
id arp;
obj1 = [[Foo alloc] init];
obj2 = [[Foo alloc] init];
[obj1 autorelease]; // obj1は、デフォルトのNSAutoreleasePoolに登録される。
arp = [[NSAutoreleasePool alloc] init];
[obj2 autorelease]; // obj2は、arpに登録される。
[arp release]; //arp解放。この時点でobj2は、解放される。
// obj1は、上位のNSAutoreleasePoolがreleaseされるまで解放されない。
}
理解を深めるためにもう一つ例を示しておきます。
- (void)methodA
{
id temp;
id arp;
int i;
for (i = 0; i < 10; i++) {
arp = [[NSAutoreleasePool alloc] init];
temp = [[[Foo alloc] init] autorelease];
// tempで現在参照されているオブジェクトは、
// arpに登録される。
[arp release]; // arp解放。
// この時点でtempで参照されるオブジェクトは解放される。
}
// この時点で10個のオブジェクトが解放されています。
}
入れ子になったNSAutoreleasePoolの利用
もうお分かりかと思いますが、NSAutoreleasePoolはいくらでも入れ子することができるのです。スレッド上で一番最近作られた NSAutoreleasePoolオブジェクトがカレントのNSAutoreleasePoolオブジェクトとして機能するわけです。さて、まずは自前のNSAutoreleasePoolを活用する前に、いくつかの注意点を示しておきます。
* NSAutoreleasePoolオブジェクトにはretainを送ってはならない。
* NSAutoreleasePoolオブジェクトにはautoreleaseを送ってはならない。
* 無用なバグと混乱を避けるために、NSAutoreleasePoolオブジェクトの生成と解放は、同じ文脈上で行うべきである。(たとえば、前述の例のように、ループ内の処理の前後など)
* retain回数 + 1 = autorelease回数がプログラム全体で成り立つことを検証する。
さて、スレッドの流れを把握しているなら、NSAutoreleasePoolオブジェクトを複数のメソッドで使うことが可能です。 Application Kit標準のNSAutoreleasePoolオブジェクトも基本的にこの方法の例に他なりません。まずは簡単なサンプルを示します。この例では、 obj2がそれにあたります。
- (void)methodA
{
id obj1;
id arp1;
arp1 = [[NSAutoreleasePool alloc] init];
obj1 = [[[Foo alloc] init] autorelease]; // obj1は、arp1に登録される。
[self methodB];
[arp1 release]; //arp解放。この時点でobj1、obj2は、解放される。
}
- (void)methodB
{
id obj2;
id obj3;
id arp2;
obj2 = [[Foo alloc] init];
obj3 = [[Foo alloc] init];
[obj2 autorelease]; // obj2は、呼出し元のarp1に登録される。
arp2 = [[NSAutoreleasePool alloc] init];
[obj3 autorelease]; // obj3は、arp2に登録される。
[arp2 release]; //arp2解放。この時点でobj3は、解放される。
// obj2は、arp1解放まで解放されない。
}
いままでは単純な例でしたが、最後に少し複雑な例を示します。それは、メソッドに戻り値がある場合の扱いについてです。以下のサンプルを見て下さい。このコードには、重要な項目が隠されています。つまり、NSAutoreleasePoolオブジェクトは、登録されているオブジェクトに対する登録回数を管理していて、自身が解放される時に、その登録回数分のreleaseを各オブジェクトに送っているだけだということです。つまり登録回数がそのオブジェクトの保持数より少なければ、NSAutoreleasePoolオブジェクトが解放された後でも、そのオブジェクトは生き続けます。この例では、retにretainを送ることでretの寿命を引き伸ばしています。
- (void)methodA
{
id obj;
id arp1;
arp1 = [[NSAutoreleasePool alloc] init];
obj = [self methodB:1];
[arp1 release]; // arp1解放。この時点でobjすなわちretは、解放される。
}
- (id)methodB:(int)i
{
id ret;
id arp2;
arp2 = [[NSAutoreleasePool alloc] init];
ret = [[Foo alloc] init]; // retの保持数は1
[ret autorelease];
if (i == 1) {
[ret retain]; // retの保持数は2になる。
// autoreleaseではなく、retainを呼ぶことで、
// arp2の寿命を超えて、arp1(もしくは、
// もっと外)の文脈まで、retで参照されるオブジェクトの
// 寿命を延ばすことができる。
} else {
ret = nil;
}
[arp2 release]; // 判定で真だったら、この時点でretの保持数は1になる。
// 判定で偽だったら、この時点でretは解放される。
return [ret autorelease]; // retを生成したので、autoreleaseを送ってから返す。
}
autoreleaseか、retain/releaseか
autoreleaseか、retain/releaseかという問題ですが、今まで見てきたようにそんなに大差はありません。状況に応じて、選択、または併用するとよいでしょう。比較的小さなあまりオブジェクトを作らないプログラムでは、Application Kit標準のNSAutoreleasePoolオブジェクトを使うことで、autoreleaseだけでプログラミングするのもよいでしょう。しかし、自前のNSAutoreleasePoolオブジェクトを使うような局面なら、retain/releaseでも同じようなものでしょう。ただ、 NSAutoreleasePoolオブジェクトを使うことでソースコードのカスタマイズが容易になるという利点はあるかも知れません。なぜなら、オブジェクトは、NSAutoreleasePoolオブジェクトが少なくとも解放されるまで有効なのですから。
retain/release/autoreleaseの適用方針
以下に垣内さん、白山さん、高橋さんから教えていただいた適用方針をまとめたものを示します。
* 基本としてオブジェクトのオーナシップを意識する。すなわち、以下の鉄則を厳守する。
【鉄則1】自分で生成したオブジェクトは、自分で解放する
【鉄則2】他人が生成したオブジェクトは、気に留めない
【鉄則3】他人が生成したオブジェクトが必要なら、必ず保持(retain)して、必要にならなくなった時点で、必ず解除(release or autorelease)する
* 可能な限り alloc-init系の生成メソッドは使わない。【鉄則2からの派生】
* alloc、init…を使う場合は必ず autoreleaseを入れる。【鉄則1】
aFoo = [[[Foo alloc] init] autorelease];
* alloc-init系以外の生成用クラスメソッドの場合は何もしない。それらのクラスメソッドは内部でalloc-init系の生成メソッドを呼んでいるため、鉄則1が適用されていると考えるべきである。【鉄則2】
aFoo = [Foo foo];
* インスタンス変数・グローバル変数・スタティック変数に代入して、参照を残す場合は、retainをかける。【鉄則3】
globalFoo = [aFoo retain];
* インスタンス変数・グローバル変数・スタティック変数の値を消す場合には、かならずreleaseかautoreleaseを入れる。【鉄則3】
//この例ではinstanceFooは、このクラスのインスタンス変数と仮定する。
- (void )setFoo:newFoo
{
[instanceFoo release];
instanceFoo = [newFoo retain];
return;
}
- (void )dealloc
{
[instanceFoo release];
[super dealloc];
return;
}
* 自分でクラスを作るときは、NSStringの+string... NSArrayの+array... のようなそのクラス専用の生成用クラスメソッドを作成して利用させる。【鉄則2の応用】
// 生成用の引数がない場合
+ foo
{
return [[[Foo alloc] init] autorelease];
}
// 生成用の引数が必要な場合
+ fooWithBar: bar
{
return [[[Foo alloc] initWithBar:bar] autorelease];
}
* 必ずループ内部でNSAutoreleasePoolを適用する。
for (i = 0; i < 10; i++) {
arp = [[NSAutoreleasePool alloc] init];
temp = [[[Foo alloc] init] autorelease];
[arp release];
}
保持と解除という方法は、理屈は分かるし簡単そうに見えます。しかし、実際にやってみると意外と難しいことがわかります。そこでCocoaでは少し楽をするための仕組みを導入しています。簡単に言えば、とりあえずなんでも入れておけるごみ袋を用意して、不要になった時点でごみ袋ごと捨てちゃうという方法です。このごみ袋にあたるのが、NSAutoreleasePoolというクラスです。
Application KitにおけるNSAutoreleasePool
さて、Cocoaの重要なフレームワークの一つであるApplication Kitの話から始めたいと思います。Application Kitは、主にGUIを持つアプリケーションを作成するためのフレームワークです。このフレームワークを利用して作ったアプリケーション(つまり、ぶっちゃけた話、ProjectBuilderとInterfaceBuilderを使って作られたNSApplicationを利用するアプリケーション) には、デフォルトで一つNSAutoreleasePoolオブジェクトが生成されています。さらに、NSApplicationが提供するイベントループ内でも、NSAutoreleasePoolオブジェクトが生成され、ループが一回転するごとに解放され、新しいNSAutoreleasePoolオブジェクトを生成します。つまり、NSAutoreleasePoolそのものを知らなくてもとりあえず使える仕組みが提供されているわけです。このごみ袋にオブジェクトを入れる方法が、NSObjectに用意されているautoreleaseメソッドです。Foundation KitとApplication Kitが提供するクラスは、基本的にNSAutoreleasePoolがある環境での動作を想定しています。
- (id)autorelease
Application Kitに準拠したプログラムの場合、任意のオブジェクトにautoreleaseを送っておくと、このオブジェクトはデフォルトの NSAutoreleasePoolオブジェクトに登録されます。そして、このプログラムが終了する直前にデフォルトの NSAutoreleasePoolオブジェクトとともに、登録されたオブジェクトがすべて解放されます。つまりautoreleaseは、retain & releaseの仕組みを使わないで、楽々とメモリ管理を行う仕組みなのです。
- (void)methodA
{
id obj = [[Foo alloc] init];
// objとして参照されているオブジェクトをNSAutoreleasePoolに登録する。
[obj autorelease];
// このメソッドを抜けると、変数objによる参照はなくなるが、
// 割り当てられたメモリは、イベントループのNSAutoreleasePoolが
// 解放される時に解放される。
}
NSAutoreleasePoolの特徴
ApplicationKitが提供するNSAutoreleasePoolを使いこなすにあたって、いくつかの注意すべき特徴があります。
* デフォルトのNSAutoreleasePoolは、プログラムの最後に(つまり、メインスレッドの末端で)解放されるので、基本的にこれに登録されたオブジェクトに割り当てられたメモリはプログラムの最後まで解放されない。
* イベントループ内で毎回生成されるNSAutoreleasePoolは、ループが一回転するごとに解放されるので、基本的にこれに登録されたオブジェクトに割り当てられたメモリはイベント処理が終わると解放される。
* autoreleaseされたオブジェクトが、基本的にそのオブジェクトが登録されたNSAutoreleasePoolがreleaseされるまで解放されないということは、逆に言えば、NSAutoreleasePoolが生きている間は、オブジェクトの生存が保障されるということを意味している。
* ただし、releaseメソッドを送ることで、このようなオブジェクトでもプログラムの途中で解放することは可能である。(これは、推奨されない方法である。基本的に、同じオブジェクトに対してautoreleaseとreleaseを併用することは混乱の元になるので、止めるべきである。 deallocについてはいわずもがな。オブジェクトのプログラマブルな解放のためには、後述する方法を用いるべきである。)
* 例外発生時には、NSAutoreleasePool(と、登録されたオブジェクト)は解放されるので、メモリリークは起こらない。(どっちにしてもプログラムが終了するので、メモリは解放される。)
* デフォルトのNSAutoreleasePoolだけで動作するようなプログラム場合、参照が切れたオブジェクトは、基本的にメモリリークと同じ状況になる。(あえて言うなら、知った上でのメモリリーク。通常のプログラムではあまり気にする必要がない。)
* NSAutoreleasePoolに登録されているオブジェクトへのアクセス手段はないので、参照の管理には注意が必要である。
自前のNSAutoreleasePoolの利用
さて、長々と引き伸ばしてきた話題に入ろうと思います。まず、Application Kitが用意しているNSAutoreleasePoolだけでは、一度のイベント処理で大量にオブジェクトを生成するような処理に対応するのが難しい場合があります。また、そもそもApplication Kitを利用しないプログラム(たとえば、コマンドラインで動作するツールなど)は、この仕組みが提供されていないわけです。そこで、自前の NSAutoreleasePoolを作成して利用する意味が出てくるのです。ここであれこれいうより、まずはサンプルコードで説明しましょう。以下のコード内のobj2を見てわかるように、実はautoreleaseメソッドを呼び出すと、スレッド内で一番最近作られた NSAutoreleasePoolにオブジェクトが登録されます。つまり、テンポラリなオブジェクトは、このように自前の NSAutoreleasePoolオブジェクトを適宜用意してやれば、任意の時点でまとめて解放できるのです。
- (void)methodA
{
id obj1;
id obj2;
id arp;
obj1 = [[Foo alloc] init];
obj2 = [[Foo alloc] init];
[obj1 autorelease]; // obj1は、デフォルトのNSAutoreleasePoolに登録される。
arp = [[NSAutoreleasePool alloc] init];
[obj2 autorelease]; // obj2は、arpに登録される。
[arp release]; //arp解放。この時点でobj2は、解放される。
// obj1は、上位のNSAutoreleasePoolがreleaseされるまで解放されない。
}
理解を深めるためにもう一つ例を示しておきます。
- (void)methodA
{
id temp;
id arp;
int i;
for (i = 0; i < 10; i++) {
arp = [[NSAutoreleasePool alloc] init];
temp = [[[Foo alloc] init] autorelease];
// tempで現在参照されているオブジェクトは、
// arpに登録される。
[arp release]; // arp解放。
// この時点でtempで参照されるオブジェクトは解放される。
}
// この時点で10個のオブジェクトが解放されています。
}
入れ子になったNSAutoreleasePoolの利用
もうお分かりかと思いますが、NSAutoreleasePoolはいくらでも入れ子することができるのです。スレッド上で一番最近作られた NSAutoreleasePoolオブジェクトがカレントのNSAutoreleasePoolオブジェクトとして機能するわけです。さて、まずは自前のNSAutoreleasePoolを活用する前に、いくつかの注意点を示しておきます。
* NSAutoreleasePoolオブジェクトにはretainを送ってはならない。
* NSAutoreleasePoolオブジェクトにはautoreleaseを送ってはならない。
* 無用なバグと混乱を避けるために、NSAutoreleasePoolオブジェクトの生成と解放は、同じ文脈上で行うべきである。(たとえば、前述の例のように、ループ内の処理の前後など)
* retain回数 + 1 = autorelease回数がプログラム全体で成り立つことを検証する。
さて、スレッドの流れを把握しているなら、NSAutoreleasePoolオブジェクトを複数のメソッドで使うことが可能です。 Application Kit標準のNSAutoreleasePoolオブジェクトも基本的にこの方法の例に他なりません。まずは簡単なサンプルを示します。この例では、 obj2がそれにあたります。
- (void)methodA
{
id obj1;
id arp1;
arp1 = [[NSAutoreleasePool alloc] init];
obj1 = [[[Foo alloc] init] autorelease]; // obj1は、arp1に登録される。
[self methodB];
[arp1 release]; //arp解放。この時点でobj1、obj2は、解放される。
}
- (void)methodB
{
id obj2;
id obj3;
id arp2;
obj2 = [[Foo alloc] init];
obj3 = [[Foo alloc] init];
[obj2 autorelease]; // obj2は、呼出し元のarp1に登録される。
arp2 = [[NSAutoreleasePool alloc] init];
[obj3 autorelease]; // obj3は、arp2に登録される。
[arp2 release]; //arp2解放。この時点でobj3は、解放される。
// obj2は、arp1解放まで解放されない。
}
いままでは単純な例でしたが、最後に少し複雑な例を示します。それは、メソッドに戻り値がある場合の扱いについてです。以下のサンプルを見て下さい。このコードには、重要な項目が隠されています。つまり、NSAutoreleasePoolオブジェクトは、登録されているオブジェクトに対する登録回数を管理していて、自身が解放される時に、その登録回数分のreleaseを各オブジェクトに送っているだけだということです。つまり登録回数がそのオブジェクトの保持数より少なければ、NSAutoreleasePoolオブジェクトが解放された後でも、そのオブジェクトは生き続けます。この例では、retにretainを送ることでretの寿命を引き伸ばしています。
- (void)methodA
{
id obj;
id arp1;
arp1 = [[NSAutoreleasePool alloc] init];
obj = [self methodB:1];
[arp1 release]; // arp1解放。この時点でobjすなわちretは、解放される。
}
- (id)methodB:(int)i
{
id ret;
id arp2;
arp2 = [[NSAutoreleasePool alloc] init];
ret = [[Foo alloc] init]; // retの保持数は1
[ret autorelease];
if (i == 1) {
[ret retain]; // retの保持数は2になる。
// autoreleaseではなく、retainを呼ぶことで、
// arp2の寿命を超えて、arp1(もしくは、
// もっと外)の文脈まで、retで参照されるオブジェクトの
// 寿命を延ばすことができる。
} else {
ret = nil;
}
[arp2 release]; // 判定で真だったら、この時点でretの保持数は1になる。
// 判定で偽だったら、この時点でretは解放される。
return [ret autorelease]; // retを生成したので、autoreleaseを送ってから返す。
}
autoreleaseか、retain/releaseか
autoreleaseか、retain/releaseかという問題ですが、今まで見てきたようにそんなに大差はありません。状況に応じて、選択、または併用するとよいでしょう。比較的小さなあまりオブジェクトを作らないプログラムでは、Application Kit標準のNSAutoreleasePoolオブジェクトを使うことで、autoreleaseだけでプログラミングするのもよいでしょう。しかし、自前のNSAutoreleasePoolオブジェクトを使うような局面なら、retain/releaseでも同じようなものでしょう。ただ、 NSAutoreleasePoolオブジェクトを使うことでソースコードのカスタマイズが容易になるという利点はあるかも知れません。なぜなら、オブジェクトは、NSAutoreleasePoolオブジェクトが少なくとも解放されるまで有効なのですから。
retain/release/autoreleaseの適用方針
以下に垣内さん、白山さん、高橋さんから教えていただいた適用方針をまとめたものを示します。
* 基本としてオブジェクトのオーナシップを意識する。すなわち、以下の鉄則を厳守する。
【鉄則1】自分で生成したオブジェクトは、自分で解放する
【鉄則2】他人が生成したオブジェクトは、気に留めない
【鉄則3】他人が生成したオブジェクトが必要なら、必ず保持(retain)して、必要にならなくなった時点で、必ず解除(release or autorelease)する
* 可能な限り alloc-init系の生成メソッドは使わない。【鉄則2からの派生】
* alloc、init…を使う場合は必ず autoreleaseを入れる。【鉄則1】
aFoo = [[[Foo alloc] init] autorelease];
* alloc-init系以外の生成用クラスメソッドの場合は何もしない。それらのクラスメソッドは内部でalloc-init系の生成メソッドを呼んでいるため、鉄則1が適用されていると考えるべきである。【鉄則2】
aFoo = [Foo foo];
* インスタンス変数・グローバル変数・スタティック変数に代入して、参照を残す場合は、retainをかける。【鉄則3】
globalFoo = [aFoo retain];
* インスタンス変数・グローバル変数・スタティック変数の値を消す場合には、かならずreleaseかautoreleaseを入れる。【鉄則3】
//この例ではinstanceFooは、このクラスのインスタンス変数と仮定する。
- (void )setFoo:newFoo
{
[instanceFoo release];
instanceFoo = [newFoo retain];
return;
}
- (void )dealloc
{
[instanceFoo release];
[super dealloc];
return;
}
* 自分でクラスを作るときは、NSStringの+string... NSArrayの+array... のようなそのクラス専用の生成用クラスメソッドを作成して利用させる。【鉄則2の応用】
// 生成用の引数がない場合
+ foo
{
return [[[Foo alloc] init] autorelease];
}
// 生成用の引数が必要な場合
+ fooWithBar: bar
{
return [[[Foo alloc] initWithBar:bar] autorelease];
}
* 必ずループ内部でNSAutoreleasePoolを適用する。
for (i = 0; i < 10; i++) {
arp = [[NSAutoreleasePool alloc] init];
temp = [[[Foo alloc] init] autorelease];
[arp release];
}
[3] [Java江湖]Java的支解之争权夺利
来源: 互联网 发布时间: 2014-02-18
[Java江湖]Java的分裂之争权夺利
精简JDK的一个实现 http://greenvm.googlecode.com/
Android: http://www.android.com/
Harmony:http://harmony.apache.com
Java自出生以后,Sun(现在是Oracle)就竭力维护Java防止分裂,但是Java分裂在不断的发生着。几个有名的Java分裂如下
- MicroSoft对Java的分裂 :这个分裂出现在Java的幼年时期,那时候Java跟现在的HTML5一样是绝对明星,大家都在追捧她。这时MS推出了Visual J,并且在自己的浏览器里安装了一个自己实现的applet插件,Visual J开发确实有自己的优势,但是并不完全兼容Sun的Java,所以毫无意外的MS成了被告了,这个官司拖了几年,最后和解,MS赔钱。详细的内容可以见李维的《Broland创奇》。这次分裂以Sun完胜为结局 。
- SWT/Swing之争 : 这两个都是完整的GUI库,对于这两者都有很多支持者和反对者,但是当人们用Java做一个GUI程序的时候,都会碰到如何选择的问题。这个也是大公司之间的倾轧的结果,SWT背后是IBM和Eclipse基金会,而Swing顶着标准的帽子,从市场占有来看SWT有后来居上的劲头。这次分裂以SWT小胜为一个阶段,后续如何发展我们拭目以待。
- Harmony和Sun : 对于使用非Sun公司JDK并不算是分裂,如Oracle、BEA(进入Oracle)、IBM、基于GNU开源的Kaffe 、OpenJDK,这些取得了授权可以叫JDK。唯独基于Apache协议的Harmony没有获得Sun的认可, Apache社区的人很火,因为按照JCP的规定这样是不行的,所以Apache社区给Sun公司写了一封公开信,要求回应,当然直到Sun被收购也没有回应。在此后,JCP投票的时候Apache一律反对,没有理由,就是要求Sun遵守JCP的规定。Servlet3.0等一系列JSR就是在这样投票下被通过。Apache社区的人积极实现相关的JSR,如Tomcat7.0就实现了Sevlet3.0。扯远了,这次分裂以Sun实际胜利和Apache道义上胜利结束,同时也为下次的分裂埋下了伏笔。
- Harmony、Android、Java :说起Android大家应该都知道,但是如果说起Harmony和Android的关系可能只有很少人知道了,在Android的API中你肯定会发现很多java.*和javax.*,这些很多都是使用了Harmony中的开发的类库,以前Harmony的开发者邮件列表中经常有android的开发者报类库的bug。Android系统使用的是Java的语法+Java的核心类库+Android的类库+Android的虚拟机,不兼容的类文件格式和打包格式。老外对于Java的核心类库加虚拟机起了一个名称叫JDK Lite,精简的JDK。这次算是Java阵营里分裂的最彻底了,但是Google的东东不叫Java,只是使用了Java语法,兼容核心类库,Sun/Oracle也没招。在Android发布后很多开源的Java社区都陆续公布了自己在Android的兼容性,很多Java开发的底层库考虑同时兼容Android和JavaSE。如果没有Harmony,google也许没有那么快发布android,毕竟核心类库的开发是一项既有体力还有脑力的劳动,所谓上面我说Harmony为下次分裂埋下了伏笔,就是指Android借助了开源的力量。这次分裂对Java程序员来说是好事,Android胜利,JavaME败北。
- GAE:GAE 呢相当于把JDK搬到了云端,具体google如何实现的呢,我们不知道,但是可以肯定的是,一定有开源代码的帮助。GAE公布后很多Java社区也是马上测试和GAE的兼容性。这次分裂影响不大,毕竟大家把自己的网站让google托管的比例不大。 在中国影响为0点几几,毕竟中国网络条件和google都不成熟。
-
未来的分裂
:google使用了Java的语法,扩大了Java程序员,没准其他的人也使用Java,而不叫Java,如Visual J#,如有可能的iPhone SDK for Java(目前还没有出现,给苹果提个醒 )。分裂意味着壮大,意味着Java不再由某个公司把持,意味在Java这个江湖里不再有老大,会变得更加多边。
1 楼
moderating
2010-07-15
j2me早就该死了,刚看到android api的时候真是觉得大快人心
gae支持java只是讨好开发人员,google还是觉得python更适合gae,gae-java用着很别扭,迟早悲剧。企业自建自营it系统的模式迟早退出,由第三方支撑的各种app市场是更好的模式,生产、运营、消费能够清晰的划分,意义很重大。所以gae这样的,当不了主角。亚马逊悲剧了
iphone不会支持java的,新的开发条款已经明确禁止object c以外的平台,包括各种虚机。乔不死对虚机的憎恨全世界都知道,sun曾经提交过jvm到app store,被拒了,flash player,拒了,GBA模拟器,拒了。不过要是乔不死也挂了,就难说了。。。这位能活到啥时候,我觉得这个才是行业最大变数把,:)
我觉得吧,传统意义的java到头了,有代沟了都。借java的壳倒是很有前途。未来也不会再出现一统江湖的语言和平台了,细分市场是趋势。未来的入门程序员该更头痛了吧。。。
gae支持java只是讨好开发人员,google还是觉得python更适合gae,gae-java用着很别扭,迟早悲剧。企业自建自营it系统的模式迟早退出,由第三方支撑的各种app市场是更好的模式,生产、运营、消费能够清晰的划分,意义很重大。所以gae这样的,当不了主角。亚马逊悲剧了
iphone不会支持java的,新的开发条款已经明确禁止object c以外的平台,包括各种虚机。乔不死对虚机的憎恨全世界都知道,sun曾经提交过jvm到app store,被拒了,flash player,拒了,GBA模拟器,拒了。不过要是乔不死也挂了,就难说了。。。这位能活到啥时候,我觉得这个才是行业最大变数把,:)
我觉得吧,传统意义的java到头了,有代沟了都。借java的壳倒是很有前途。未来也不会再出现一统江湖的语言和平台了,细分市场是趋势。未来的入门程序员该更头痛了吧。。。
2 楼
Teok
2010-07-16
j2me还是死吧。。。前2天跟了一个模拟器上不能复现的真机bug,着实让我恶心不已。。
想想android的联机调试。。哎
想想android的联机调试。。哎
3 楼
yvfish
2010-07-16
话说,天下大势,分久必合,合久必分。
我等小民只是混口饭吃,这些大事咱们就当听评书好了。。。
我等小民只是混口饭吃,这些大事咱们就当听评书好了。。。
4 楼
zhs2472
2010-07-16
顶楼上,混饭吃要紧
5 楼
nisen
2010-07-16
iPhone上模拟器不火,但是Android上的模拟器估计会很火。当然现在也有了很多模拟器。J2ME程序在Android上会以模拟器方式出现。
iphone不会支持java的,新的开发条款已经明确禁止object c以外的平台,包括各种虚机。乔不死对虚机的憎恨全世界都知道,sun曾经提交过jvm到app store,被拒了,flash player,拒了,GBA模拟器,拒了。不过要是乔不死也挂了,就难说了。。。这位能活到啥时候,我觉得这个才是行业最大变数把,:)
moderating 写道
iphone不会支持java的,新的开发条款已经明确禁止object c以外的平台,包括各种虚机。乔不死对虚机的憎恨全世界都知道,sun曾经提交过jvm到app store,被拒了,flash player,拒了,GBA模拟器,拒了。不过要是乔不死也挂了,就难说了。。。这位能活到啥时候,我觉得这个才是行业最大变数把,:)
6 楼
francis.xjl
2010-07-17
GAE我觉得还不成熟,J2EE规范支持得仍然远远不够。
7 楼
nisen
2010-07-18
GAE应当不会支持JavaEE规范,或者宣称自己符合JavaEE规范。因为他们玩法不是规范的玩法。
francis.xjl 写道
GAE我觉得还不成熟,J2EE规范支持得仍然远远不够。
8 楼
linkerlin
2010-07-19
J2ME不会马上淘汰的,我现在用的E63上还有很多J2ME应用呢。
很好用啊。
我觉得普通用户不会在意到底是啥技术的。
好用便宜就行啊。
真的玩技术的有多少呢?
普通用户的市场才是最大的吧?
很好用啊。
我觉得普通用户不会在意到底是啥技术的。
好用便宜就行啊。
真的玩技术的有多少呢?
普通用户的市场才是最大的吧?
9 楼
nisen
2010-07-21
JavaME至今仍是装机最多的手机开发平台。
linkerlin 写道
J2ME不会马上淘汰的,我现在用的E63上还有很多J2ME应用呢。
很好用啊。
我觉得普通用户不会在意到底是啥技术的。
好用便宜就行啊。
真的玩技术的有多少呢?
普通用户的市场才是最大的吧?
很好用啊。
我觉得普通用户不会在意到底是啥技术的。
好用便宜就行啊。
真的玩技术的有多少呢?
普通用户的市场才是最大的吧?
10 楼
carlkkx
2010-07-22
SWT/Swing之争 : 这两个都是完整的GUI库,对于这两者都有很多支持者和反对者,但是当人们用Java做一个GUI程序的时候,都会碰到如何选择的问题。这个也是大公司之间的倾轧的结果,SWT背后是IBM和Eclipse基金会,而Swing顶着标准的帽子,从市场占有来看SWT有后来居上的劲头。这次分裂以SWT小胜为一个阶段,后续如何发展我们拭目以待。
——————————————————————————————
如果不基于Eclipse,独立的软件来说Swing远远多于SWT,何来什么SWT小胜。
——————————————————————————————
如果不基于Eclipse,独立的软件来说Swing远远多于SWT,何来什么SWT小胜。
11 楼
nisen
2010-08-02
小胜只是因为它是后来者,却占据了很大的份额。诚然很多有多年历史的程序都是用Swing来开发的如ArgoUML、freemind、JEdit,但是Swing却没有保住自己老大的地位,新的项目开始之前都会对选择SWT/Swing进行取舍。关于小胜还是平分秋色,如果后来者抢了前面的大部分市场可以谓之小胜,你称之为平分秋色也可,但是分裂已经形成了,而且还会继续。
carlkkx 写道
SWT/Swing之争 : 这两个都是完整的GUI库,对于这两者都有很多支持者和反对者,但是当人们用Java做一个GUI程序的时候,都会碰到如何选择的问题。这个也是大公司之间的倾轧的结果,SWT背后是IBM和Eclipse基金会,而Swing顶着标准的帽子,从市场占有来看SWT有后来居上的劲头。这次分裂以SWT小胜为一个阶段,后续如何发展我们拭目以待。
——————————————————————————————
如果不基于Eclipse,独立的软件来说Swing远远多于SWT,何来什么SWT小胜。
——————————————————————————————
如果不基于Eclipse,独立的软件来说Swing远远多于SWT,何来什么SWT小胜。
最新技术文章: