ラベル Objective-C の投稿を表示しています。 すべての投稿を表示
ラベル Objective-C の投稿を表示しています。 すべての投稿を表示

2010年9月4日土曜日

[Objective-C] リファレンスカウンタとの戦い

以前かいたObjective-Cのリファレンスカウンタについて,再び考える.

[Objective-C] 詳解 Objective-C 2.0 リファレンスカウンタ 不明なところ - トウヨウリンゴ
http://newringo.blogspot.com/2010/05/objective-c-objective-c-20.html

コードはこちら.

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

int main(void)
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
  NSObject *obj = [[NSObject alloc] init];
  printf("init: %d\n",[obj retainCount]);
  [obj retain];
  printf("retain: %d\n",[obj retainCount]);
  [obj retain];
  printf("retain: %d\n",[obj retainCount]);

  [obj release];
  printf("release: %d\n",[obj retainCount]);
  [obj release];
  printf("release: %d\n",[obj retainCount]);
  [obj release];
  /* 実行するとエラーになるはずなのだが・・・ */
  printf("release: %d\n",[obj retainCount]); 

  [pool drain];

  return 0;
}

そして,今日わかったのは,詳解 Objective-C 2.0と同じ結果を得るためには,以下のコンパイルをすればよい.

gcc -framework Foundation -m32 reference.m

結果
init: 1
retain: 2
retain: 3
release: 2
release: 1
objc[2758]: FREED(id): message retainCount sent to freed object=0x103f60
Illegal instruction

ただ,このオプションで本通りになるというのは,なっとくいかない.

-m32のオプションなしの場合

結果
init: 1
retain: 2
retain: 3
release: 2
release: 1
release: 1

64bit用では,同様の結果が得られないのは,なぜか.
さっぱりだ.

2010年7月26日月曜日

[Squeak][Objective-C] へっぽこSqueak SmalltalkユーザによるSqueak Smalltalkで考えるObjective-C その1

私はinputはしてもoutputをあまりしてこなかったので,文章を書くのが下手.
未だに知識がしっかりつかないのは,outputがきちんとできないため.

ということで,需要があるかわかりませんが,へっぽこSqueak SmalltalkユーザによるSqueak Smalltalkで考えるObjective-Cを書いてみます(おそらく大学の身内しか必要ないだろう).

でも,時間がないので,テキトーなメモです.

Hello World

Squeak Smalltalk
Transcript cr; show:'Hello World'.

Objective-C
// file name   ->  test.m
#import<foundation/foundation.h>
int main(void){
  NSLog(@"Hello World");
  return 0;
}

実行方法
Squeak Smalltalk
"Workspaceに記述し,do it"

Objective-C

端末で以下のような方法でコンパイル
$ gcc -framework Foundation  test.m


リテラル
Objective-CはC言語のリテラルが使えます.

コメント
Squeak Smalltalk
ダブルクオーテーションで囲みます.

Objective-C
// または,/* ・・・*/ です.




Squeak Smalltalk
全てオブジェクトとして扱います.

Objective-C
Cの基本データ型の数値とNSNumberクラスのインスタンスがある.
NSIntegerは普通のintまたはlong.


NSNumber *number = [NSNumber numberWithFloat: 1.0];

文字列

Squeak Smalltalk
シングルクオーテーションで囲みます.
'文字列です'

Objective-C
C言語の文字列以外に,NSStringのインスタンスの文字列があります.

ダブルクオーテーションで囲み,先頭に@を付けます.
@"文字列です"

代入
Squeak Smalltalk
 :=

Objective-C
=

文末
Squeak Smalltalk
."ピリオド"

Objective-C
; //セミコロン

メッセージ式

Squeak Smalltalk
'Ringo no Tane' size. "文字列の長さを求める"

Objective-C
[ ] で囲むことにより,メッセージが送信できます.Objective-Cにはメッセージ式による優先順位がない.優先順位は括弧の付け方で決定される.
[@"Ringo no Tane" length]; //文字列の長さを求める

算術演算

Squeak Smalltalk
Smalltalkでは,メッセージ式の優先順位で計算をする.

Objective-C
C言語と同様な優先順位で行なわれる.

カスケード

Squeak Smalltalk
; "セミコロン"


"カスケードなし"
Transcript cr.
Transcript show:'Hello'.

"カスケードあり"
Transcript cr; show:'Hello'.

Objective-C
存在しません.

ブール値

Squeak Smalltalk
true "真,Trueクラスのインスタンス"
false "偽,Falseクラスのインスタンス"
nil "不定"

Objective-C
Bool型はブール値を扱うための方
YES //真を表す定数 0でない値
NO //偽を表す定数 0
nil //nullのオブジェクトを示す.nilはid型の空ポインタ.値は0.

制御構造

if

Squeak Smalltalk
if文はありませんが,ifに相当するメソッドが実装されています.

1 > 0 ifTrue:[  Transcript show:'Ha Ha Ha!!'; cr. ].
Objective-C

if(1 > 0){
  printf("Ha ha Ha!\n");
}

while

Squeak Smalltalk
i := 0.
[i<4] whileTrue:[ Transcript cr;show:'hoge'. i := i + 1. ].

Objective-C
int i = 0;
while(i<4){
  printf("hoge\n");
}

for

Squeak Smalltalk
for文のように振る舞うto:, to:do:, to:by:do:があります.


1 to: by:1 10 do:[:v | Transcript cr;show:v ].

Objective-C

int i;
for(i=1; i<11; i=i+1){
  printf("%d",i);
}
SmalltalkのイテレータとObjective-C高速列挙
別の時に説明します.

switch

Squeak Smalltalkにはありません.
余談,SmallTalk R4.1 http://smalltalk.smalltalk-users.jp/ ならあります.

Objective-C
略します.


次回は,クラス定義について書こうと思います.

[Objective-C] 基礎から学ぶ iPhoneアプリ開発

「Objective-C逆引きハンドブック」の著者である林 晃さんが,新しい本を出されました.

「基礎から学ぶ iPhoneアプリ開発」

昨日本屋で発見.思わず購入.

Core DataについてがAppleのDocumentより分かりやすいことと,具体的なサンプルがあって,良書です.



Objective-C逆引きハンドブックは,萩原さんの詳解Objective-C 2.0と一緒に持っておくとかなりいい.


Objective-Cのサンプルコードが,これほど多くまとめられているものは私の知っている限り数少ないと思う.
特に日本語で,非常に意味のあるサンプルコードばかりなので,Objective-Cをしっかりと使いたいひとにはお勧めだと思います.


2010年7月16日金曜日

[Objective-C] Objective-Cのカテゴリを使ってみる

Objective-Cのself,superを確認してみるのプログラムをObjective-Cのカテゴリを使ってきちんと動作するようにしてみる.

#import <Foundation/Foundation.h>

@interface NSObject (MyTest)
- (id) methodA;
@end

@implementation NSObject (MyTest)
- (id)methodA
{
  NSLog(@"NSObject");
}
@end

@interface TestA:NSObject
- (id) methodA;
- (id) methodB;
- (id) methodC;
@end

@implementation TestA
- (id) methodA
{
  NSLog(@"class A");
}

- (id) methodB
{
  [self methodA];
}

- (id) methodC
{
  [super methodA];
}
@end

@interface TestB : TestA
- (id) methodA;
@end

@implementation TestB
- (id) methodA
{
  NSLog(@"class B");
}
@end

int main(void){
  SAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  TestB *objB = [[TestB alloc] init ];
  //selfの確認
  [objB methodB];
  //superの確認
  [objB methodC];
  return 0;
}

実行結果

2010-07-16 06:55:59.383 a.out[512:903] class B
2010-07-16 06:55:59.385 a.out[512:903] NSObject

カテゴリを用いたことで,NSObjectにmethodAを実装することができました.

Objective-Cのカテゴリはメソッドの整理だけではなく,既存クラスにmethodを追加することができます.これは非常に便利ですが,やはり既存クラスに追加するのは,できる限りさけたいものです.

カテゴリで注意しなければならないのは,インスタンス変数を付加できないということ,そして,既存のクラスのメソッドと同じ名前でメソッドを定義すると,上書きができてしまうことです.これはメリットでもありデメリットでもあります.上書きした場合,元のメソッドは呼び出すことはできません.

[Objective-C] Objective-Cのself,superを確認してみる

何をいまさらと言われてしまうが,最近いろいろな言語をやっていたりすると不安になってきたので,一応確認.

#import <Foundation/Foundation.h>

@interface TestA:NSObject
{
}
- (id) methodA;
- (id) methodB;
- (id) methodC;
@end

@implementation TestA
- (id) methodA
{
  NSLog(@"class A");
}

- (id) methodB
{
  [self methodA];
}

- (id) methodC
{
  [super methodA];
}
@end

@interface TestB : TestA
{
}
- (id) methodA;
@end

@implementation TestB
- (id) methodA
{
  NSLog(@"class B");
}
@end

int main(void){
  TestB *objB = [[TestB alloc] init ];
  //selfの確認
  [objB methodB];
  //superの確認
  [objB methodC];
  return 0;
}

このコードをコンパイルすると以下の警告が表示されます.

main.m: In function ‘-[TestA methodC]’:
main.m:24: warning: ‘NSObject’ may not respond to ‘-methodA’
main.m:24: warning: (Messages without a matching method signature
main.m:24: warning: will be assumed to return ‘id’ and accept
main.m:24: warning: ‘...’ as arguments.)

NSObjectにはmethodAを実装されていないため,もしかしたら動作ができないかもしれないと警告が表示されます.
警告を無視して,実行してみます.


2010-07-16 06:30:27.310 a.out[430:903] class B
2010-07-16 06:30:27.313 a.out[430:903] -[TestB methodA]: unrecognized selector sent to instance 0x10010d980
2010-07-16 06:30:27.315 a.out[430:903] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TestB methodA]: unrecognized selector sent to instance 0x10010d980'
*** Call stack at first throw:
(
0 CoreFoundation 0x00007fff837b6cc4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00007fff88f6c0f3 objc_exception_throw + 45
2 CoreFoundation 0x00007fff83810140 +[NSObject(NSObject) doesNotRecognizeSelector:] + 0
3 CoreFoundation 0x00007fff83788d4c ___forwarding___ + 860
4 CoreFoundation 0x00007fff83784e28 _CF_forwarding_prep_0 + 232
5 a.out 0x0000000100000d51 -[TestA methodC] + 56
6 a.out 0x0000000100000dfe main + 136
7 a.out 0x0000000100000ccc start + 52
8 ??? 0x0000000000000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
Abort trap


[objB methodB]では,TestBのmethodAが実行されます.

[objB methodC]はTestAのスーパークラスであるNSObjectのmethodAを実行しようとしますが,NSObjectにはmethodAがないので,実行することができないので,エラーになります.

他の言語でも,同様なプログラムを書くとself,superの動作を確認することができますので,お試しあれ.
あと,このプログラムから分かるように,Objective-Cは実装されていないメソッドがあっても,コンパイル時に警告はだしますが,実行できるということが重要です.

2010年7月10日土曜日

[Objective-C] 詳解 Objective-C 2.0

6/10/2008
http://newapplesho.blogspot.com/search/label/Book より

詳解 Objective-C 2.0の本が発売されています.
作者はもちろん荻原さん.


今,お世話になっています.7/10/2010

Objective-Cを非常に詳しく説明している.サンプルコードが少ないが,ある程度オブジェクト指向言語を学んだ人なら何となく読めると思う.
Objective-Cの文法,考え方,用語をしっかりと学び人にお勧めです.

[Objective-C] たのしいCocoa プログラミング

7/19/2007
http://newapplesho.blogspot.com/search/label/Book より

先日,本屋でこんな本を発見.
即買ってしまいました.



木下さんの本はいつか全て買いたいと思っていますが,特にこの本はプログラミングがぜんぜんできない僕にはよさそうです.
いよいよObjective-Cの世界へいけそうかな?

今はiPhone Programmingを勉強中.
この本はObjective-Cを学ぶ際に購入して,よかったと思う.7/10/2010

Objective-Cをかなり優しく解説しているため,初めてObjective-Cを学ぶ人にお勧めです.オブジェクト指向の解説もあり,C言語経験者でもわかるように記述しています.

2010年5月17日月曜日

[Objective-C] 詳解 Objective-C 2.0 リファレンスカウンタ 不明なところ

先日,萩原さんの詳解 Objective-C 2.0 リファレンスカウンタのプログラムを実行してみたら,出力結果が予想と異なるものであったので,現在も困っています.

困っているのは,以下のコードです.
#import <Foundation/Foundation.h>
#import <stdio.h>

int main(void)
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
  NSObject *obj = [[NSObject alloc] init];
  printf("init: %d\n",[obj retainCount]);
  [obj retain];
  printf("retain: %d\n",[obj retainCount]);
  [obj retain];
  printf("retain: %d\n",[obj retainCount]);

  [obj release];
  printf("release: %d\n",[obj retainCount]);
  [obj release];
  printf("release: %d\n",[obj retainCount]);
  [obj release];
  /* 実行するとエラーになるはずなのだが・・・ */
  printf("release: %d\n",[obj retainCount]); 

  [pool drain];

  return 0;
}


コンパイル  gcc -framework Foundation reference.m
環境 os 10.6.2

出力結果
init: 1
retain: 2
retain: 3
release: 2
release: 1
release: 1


obj にreleaseメッセージを3回送ったあとに,参照カウンタを見ようとしたらエラーになるはずですが,参照カウンタが1と表示されてしまいます.
何故なんでしょうか.



2010年5月15日土曜日

[Objective-C] どう書く?org IPv4アドレスのマスクの変換 をやってみた.

どう書く?org IPv4アドレスのマスクの変換 をObjective-C でやってみました.
コードを公開しますけど,いじめないでくださいね.


#import <Foundation/Foundation.h>

int main(void){

int prefixNumber = 0;
int i,j,temp;

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSString *addressString = [NSString string];

//NSString *subnetString = @"255.255.255.0";
NSString *subnetString = @"255.255.255.240";
//NSString *subnetString = @"128.0.0.0";
//NSString *subnetString = @"255.248.0.0";

NSArray *subnetStringItems = [subnetString componentsSeparatedByString:@"."];

for(i = 0; i < 4; i++){
temp = [[subnetStringItems objectAtIndex:i] intValue];
for(j=0;j<8;j++){
prefixNumber += (temp & 1);
temp >>= 1;
}
}
NSLog(@"prefixNumber=%d",prefixNumber);

for(i = 0; i < 4; i++){
if(prefixNumber >= 8){
addressString = [addressString stringByAppendingString: @"255"];
prefixNumber = prefixNumber - 8;
}else if(prefixNumber > 0){
temp = 0;
temp = 255 - ((1 << (8-prefixNumber)) - 1);
addressString = [addressString stringByAppendingString: [ NSString stringWithFormat : @"%d", temp ]];
prefixNumber = 0;
}else{
addressString = [addressString stringByAppendingString: @"0"];
}

if(i<3){
addressString = [addressString stringByAppendingString: @"."];
}

}
NSLog(@"addressString=%@",addressString);

[pool drain];

return 0;
}


どう書く?org IPv4アドレスのマスクの変換
http://ja.doukaku.org/253/nested/

2010年5月5日水曜日

[Objective-C] UIKitの本

UIKitについて学びたいと思っていたら,このような本が出ていました.



先日,本屋で少し内容をみたら,とてもすばらしい内容でした.
その日は手持ちがなかったので,後日購入したいと思います.

[追記] 購入しました.
Interface Builderを用いずにUIを開発するスタイルで書かれており,どのようにしたらこのUIが記述できるのかがハッキリしてとてもいいです.
この中に書かれているサンプルはどれも実際に利用できそうなものばかりで,非常に勉強になります.

UIKitを学びたい人にお勧めです!