それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Objective-C 入門。覚えること

今更ながら、クイックルックアプリとか書きたくなってObjective-Cを覚えている。

オブジェクトについて使い方を詰まったサンプルコードを書いておいた

変数

変数は、宣言=>初期化=>代入の3ステップ

変数の宣言
NSString *str;
char  *cp;
id my_obj;

C言語スタイルで変数を宣言する。id の場合には ポインタ演算子*は付けない

変数宣言短縮形
NSString  *str = @"Hello World";
char*cp  = "Hello World";

文字の場合とくに、変数宣言&初期化&代入はC言語っぽいスタイルになるように工夫されている。
int/uint や char も使えるので、使ってどうぞ。

変数の出力

コンソールに出力するときは、 NSLog や printf を最初に覚えるとイイ

printf("%s",  [@"あああ"  UTF8String ]  );
NSLog(@"あああ");

@マークは重要

@マークはObjective-C特有の機能を表現するために、ソースコードで頻繁に使う。

オブジェクトの定義

「クラスの宣言」「クラスの実装」を分ける。C言語で「関数の宣言」と「関数の実装」が分けられるのと同じ。

定番のAnimalクラスを実装する

Animalクラスを作る。コンストラクタの引数で鳴き声を与えるものを作ります。

クラスの宣言
@interface Animal : NSObject
  (略
@end
クラスの実装

クラス変数や実体の定義は別に書く。このへんはC++も同じだね。

@implementation Animal
  (略
@end
  • @interface 〜@end :クラス定義
  • @implementation 〜@end :クラス実装
インスタンス変数:

@property で宣言する。

@interface Animal : NSObject
  (略
  @property NSString *name;
  (略
@end
インスタンスメソッド:宣言

メソッドは - を定義する。

@interface Animal : NSObject

  (略
  -(NSString *) info;
  (略
@end
インスタンスメソッド:実装

メソッドの実装も同じ

@implementation Animal

- (void) bark{
    NSString *a = self.voice;
    const char *cp =   [a UTF8String];
    printf("「%s\n", cp);
}

@end

実装の各ファイル

実装を Animal.m 定義をAnimal.h に書くのが一般ルール。
もちろん同一ファイルに書いても動く

このへんはコンパイラに渡す設定次第なので、何とでも。ファイルにベタ書きしたって構わない。

コンストラクタインスタンス生成

NSObjectを継承したインスタンスを生成をするのもの、C言語と同じ手続きですね。

変数の仕様を宣言して、メモリを確保して、オブジェクトをコピーする。

      Animal  *a;            //変数名を宣言
      a = [Animal alloc];   //変数初期化
      a = [a init];         //インスタンス生成

これらの手続きは、ひとまとめにできる。

      Animal  *a = [ [Animal alloc] init];

ひとまねに書くことが出来る。alloc や init は状況によって変わる。
alloc/initでnew 同等とするのは褒められた説明じゃない。

コンストラクタ関数を定義する。


[super init] をして、return self すれば、init の代替になれる。オーバーライドも出来る。

@implementation Animal
 (略

  -  ( id ) init { 
      self  =  [ super init ];
      self.name=@"未確認生物";
      self.voice=@"□□□□□□";
      return self;
}
(略

@end

return self する感じで動くようだ。

コンストラクタ関数(引数付き)を定義する。

オーバーロード的は出来ない*1ので、別のコンストラクタを作って関数に名前をつける。

@implementation Animal
  (略
   - (id)initWithNameAndVoice: (NSString*)n :(NSString*)v 
  {
         self = [super init ] ;
         self.name = n;
         self.voice = v;
         return  self;
  }
  (略
@end

インスタンス作成のメソッドを作ってつかう事ができる。

ループ for in


forEach 相当な for in がある。 while / for はC言語と同じ。

foridin  animals ) {
            printf( "%s" , [[e info ] UTF8String]  );
            [e bark];
        }

  for in ループは id で全て受けられる。 id はObjective-Cのオブジェクトそのものを指す。
 定義済み変数に入れるならキャストする。

キャスト

  idに入れたらキャストして使う。

 for( id key in  dict ) { 
   NSString *str = (NSString  *) key;
  }

配列

配列はC言語スタイルのものと、NSArrayベースな物がある。
シンタックスシュガーや新しい書き方が定義されていて、そのほうが便利なので、それだけ覚えれればイイ

固定長の配列
  Animal  * list[] = {};//要素数1個の配列

 C言語スタイルで書けることが特徴ですね。 実際には NSArray を使う

可変長配列

NSMutableArrayを可変長で使います。

NSMutableArray *animals 
    = [ [ NSMutableArray  alloc ]  init];

可変長配列は通常クラスと同等に配列。

イテレーションするので便利。JavaでいうIteratorRubyでいうEnumerateとして使える。

連想配列(ディクショナリ)

 ディクショナリでハッシュマップを作れます。

NSDictionary*dict  = @ {  
                  @"ドッグ"  :  @"わんわん",
                  @"キャット" : @"にゃーん",
                  @"ピジョン" : @"くるっぽー",
                  @"ピッグ" : @"ぶひぶひー",
                                  };

 初期化で代入時に、@{} のシンタックスシュガーを使うのが楽です。

インスタンスのメソッドの呼び出し

メソッドとは言わずにオブジェクトにメッセージを送ると言うらしい

[obj message];

[foo bar ] 形式と foo.bar 形式

     Animal *a = [ [ Animal alloc ] init ];
     [a bark]; 
     Animal  *a = [[ Animal  alloc ] init ];
     a.bark;//[a bark]の代替でプロパティへのアクセスと同等にメソッドを呼べる。
id で変数を一括で受けても大丈夫

id 型がすべてのオブジェクトの参照先に使える。したがって id を使って変数宣言してもイイ。

      id a = [ [ Animal alloc ] init ];
      [a  bark];
      a.bark;      //ドットアクセスはコンパイル時に型チェックエラー

使い方をまとめた、サンプルコードを作った



gist7283465

*1:できるのかな?ちゃんと調べてない