C++使いがObjective-Cに触れてみて思ったこと

※2019/12/16追記: 当時の理解不足で少しオーバーな表現や誤りが含まれていたのでその部分だけ修正しました

私は普段はC++で開発をしています。そんな私がObjective-C(Foundation)を数日間勉強してみて思ったことを書いてみます。C++使いに読みやすいように、Objective-C用語もあえてC++っぽく呼んでいたりします。

印象

初めてObjective-Cのコードを見たときに全く理解できずたじろぎました。関数(メソッド)の定義と呼び出し方がC++などとは全然違っていて初めて見る形式だったからです。
しかし勉強を始めてみて数時間でその不安は吹っ飛びました。むしろC++からC#に移るよりも楽なんじゃないかと思うぐらいです。メソッドの定義と呼び出し方が分かればあとはそんなに難しくないはずです。

C++やCと何が違うのか

ペースはC言語で、C言語の記述がそのまま使えます。その上でObjective-C特有の部分は@や[]で区別されたところに記述します。Foundationなどの機能を呼び出したい時にObjective-C特有の記述をします。Objective-C特有の記述で特徴的なのはメンバ関数の定義方法と呼び出し方法。
具体的に書くと以下のように違います。

[C++]

class CMyClass {
    int GetInformation();
};

void work()
{
    CMyClass* myObject = new CMyClass;
    int information = myObject->GetInformation();
    delete myObject;
}


[Objective-C]

@interface MyClass : NSObject {
}
- (int) getInformation;
@end

void work()
{
    MyClass *myObject = [[MyClass alloc] init];
    int information = [myObject getInformation];
    [myObject release];    // ※2019/12/16追記: ARC利用時は手動のreleaseは不要です
}


C++と呼び出し方は違いますが、全く違うことをやっているわけではないのがわかると思います。

違うのは記述方法だけでなくてメンバ関数が呼び出されるメカニズムもです。C++だとコンパイル時に飛び先のアドレスが解決されますが、Objective-Cだと実行時に解決します。そのまま使うと関数呼び出しのオーバーヘッドが大きいので注意。詳しくないけどセレクタを使った回避策もあるらしい。細かくて回数が莫大なループ内で呼び出す要な場合は回避したほうがいいかもしれません。iOSアプリ開発においては無視できる程度のオーバーヘッドであることが大半です(2019/12/16追記)
基本的な考え方はC++と同じです。おまけにメンバ変数にアクセスするためのメンバ関数(GetterやSetter)を自動生成してくれちゃう機能まであり、C++よりも便利な記述が言語的に備わっています。クリティカルセクションの制御なんかも言語レベルでサポートされています。

フレームワークについて

Objective-CMacOSXiOSのアプリをつくるのに主に使用されています。そしてそのターゲット用にCocoa(iOS用はCocoa touch)というフレームワークがあり、Objective-Cプログラミングではそれを使います。Windowsでいう.NET Frameworkのようなものに当たるでしょうか。
コーディングに密接に絡んでくるのがFoundationと呼ばれるもので、C言語で言う標準関数のようなものがここにある感じです。この中のNSObjectっていうクラスがかなり重要でObjective-Cプログラミングの要。インスタンスの確保・開放などはこのクラスに実装されている機能を使うことになります。
私はいまこのあたりの使い方とiOSのUI用のクラス(UIButtonなど)の勉強中です。

総括

言語の違いは大した障害とならない感触です。純粋に新しいフレームワークの使い方を覚えていくことに比重を置くことになると思います。