Objective-C の文法を覚える!

JavaScript の文法はだいたいわかったので,Objective-C を覚える!

コマンドラインでコンパイルできるようにしてから,
Page Not Found - Apple Developer
ここで覚えてくのが今の予定.

ターミナルでコンパイル

まずは,UbuntuでObjective-Cをコンパイルする - 0xDB を参考に素の Objective-C をコンパイルしてみる.

何をインクルードする必要があったのか忘れたので Objective-Cでダックタイピング - @kei10in の日記 を参考にコード書いて実行してみたけど,illegal hardware instruction っていうのが出てだめだ.

とりあえず,これは後で調べる.

#import <stdio.h>
#import <objc/Object.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}

をコンパイルして実行した.

% gcc -lobjc test.m
% a.out
Hello, World!

前途多難そうだけど,とりあえず進む.


とは言ったもののちょっとしらべる.

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

@interface HelloWorld : NSObject
- (void) hello;
@end

@implementation HelloWorld
- (void) hello { printf("Hello, World!\n"); }
@end


int main(int argc, char **argv){
    id obj = [HelloWorld alloc];;

    [obj hello];

    return 0;
}

を↓みたいにコンパイル,実行したら問題なかった.

% gcc -framework Foundation test.m
% a.out
Hello, World!

しっかり調べたわけじゃないので微妙だけど,Mac だと objc/Object.h の Object を使うと簡単には実行できなそう.

素直に Foundation/NSObject.h を使うことにする.

Apple の Objective-C 2.0 プログラミング言語

Apple の Objective-C の解説を読み進める.

最初はあんまり面白くないお話.だらだら読み進める.

型のイントロスペクション

やっとコードがかける!!

NSObject では isMemberOfClass,isKindOfClass というのでクラスの型情報とかの検証ができるみたい.

Python で言うところの isinstance とかかな?

とりあえず使ってみる.

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

@interface Speaker : NSObject
- (void)speak;
@end

@implementation Speaker
- (void)speak { printf("I'm speaker.\n"); }
@end

@interface RoudSpeaker : Speaker
@end

@implementation RoudSpeaker
- (void)speak { printf("I'M SPEAKER!!!\n"); }
@end


void say(Speaker* speaker) {
    if ( [speaker isKindOfClass:Speaker] ) {
        [speaker speak];
    }
    if ( [speaker isMemberOfClass:RoudSpeaker] ) {
        [speaker speak];
    }
}

int main(int argc, char **argv){
    Speaker* speaker1 = [Speaker alloc];
    Speaker* speaker2 = [RoudSpeaker alloc];

    say(speaker1);
    
    printf("\n");

    say(speaker2);
    
	return 0;
}

そしてコンパイル.

% gcc -framework Foundation test.m                      
test.m: In function ‘say’:
test.m:22: error: expected expression before ‘Speaker’
test.m:25: error: expected expression before ‘RoudSpeaker’

ありゃ! エラーだ.

ちょっと調べる.

にサンプルがあった.

if ([obj1 isMemberOfClass:[NSObject class]]){
NSLog(@"YES");
}else{
NSLog(@"NO");
}

サンプルによると引数として [NSObject class] みたいな感じにしないといけないらしい.

say 関数をちょっと書き換える.

void say(Speaker* speaker) {
    if ( [speaker isKindOfClass:[Speaker class]] ) {
        [speaker speak];
    }
    if ( [speaker isMemberOfClass:[RoudSpeaker class]] ) {
        [speaker speak];
    }
}

やたー,出来た!

% gcc -framework Foundation test.m
% a.out
I'm speaker.

I'M SPEAKER!!!
I'M SPEAKER!!!
いったんここまで.

読んでてもコード書いて試すみたいなことがやりにくいわ…

先に NSString を覚えよう…