最近はiOSアプリの勉強をしています。 都合により、SwiftじゃなくてObjective-Cで書いています。 iOSアプリ開発では言語というよりSDKであるUIKitの使い方を覚えるほうが大事みたいなので、Objective-Cで勉強したとしても無駄にはなりません。

この記事ではObjective-Cで書いていて気になったものをちょっとメモ。


疑問

XcodeでViewControllerを作成するとヘッダーファイルと.mの実装ファイルができる。 ヘッダーの方には@interfaceのクラス宣言が書かれていて、.mの方で@implementationを使って実際にメソッドの処理を記述するようになっています。

しかし、自動生成して作ったファイルには実装のほうにも@interfaceがある。 これはなに?

// HogeController.m

#import "HogeViewController.h"

@interface HogeViewController ()

@end
// ↑これ

@implementation HogeViewController

/*
...
*/

@end

クラス宣言がダブってエラーになったりしないのでしょうか。というかここの中身は、なにも書かなくていいの?

そのうえ、クラス名のあとに()がついていて、ただのクラス宣言と違った特殊な雰囲気を醸し出しています。お前はいったいなんなんだ。

クラス拡張

調べてみれば、これはクラス拡張というものらしいです。

Objective-Cには既存のクラスにあとづけでメソッドを追加できるカテゴリという機能があります。 カテゴリは@interface NSString (カテゴリ名)のように、@interfaceのクラス名のあとにカテゴリをカッコで囲むようになっています。

そのカッコの中身が無くなったのがクラス拡張です。

実際にはカテゴリとクラス拡張はまったく違う機能みたいなのですが、今のところ似たようなものと理解しておけばいいと思います。

要するに、すでにクラス宣言した内容にあとづけでいろいろなメソッドやプロパティを追加できるのがクラス拡張です。

使いみち

privateなメソッドやプロパティを宣言するために使います。

ヘッダーファイルの@interface内に書かれている内容は、importしたファイルからは丸見えになります。 しかし、内部の処理は隠蔽して外部には見せたくないときもありますよね。

そういうときはクラス拡張の中に書くことで、ヘッダーファイルにはそのメソッドなどの情報がなくなりますので、内部だけで使用することができます。

JavaやC++ではprivateを付ければいいのですが、見た目も特殊なObjective-Cではこういうテクニック?を使うみたいです。

参考