Help us understand the problem. What is going on with this article?

意図せずObjective-C を読まなければいけなくなった Swift エンジニアへ贈る Objective-C読み方まとめ

自己紹介

こんにちは! iOSエンジニアのやまたつ です☺️
Oshidoriというアプリを個人で開発し、リリースしています!!!
8月から参画している現場のプロダクトに Objective-C が4割くらい入っていました!(予想外)
ソースコードを読み解くのに、Objective-C を学ばなければついていけなくなるので勉強中です!

モチベーション

正直、Objective-C を学ぶモチベーションはほぼありません!
というのも、これから新規アプリを作成するときに Objective-C を選択する企業はほとんどないと思うし、Swift の方がモダンで書きやすいからです。

しかし Swift が出てきたのも2014年と最近で、それまでに作られたアプリは Objective-C で書かれています。
昔からある案件では Objective-C で書かれたアプリがまだまだ存在し、Objective-C を読めた方が重宝されます。
私は案件を探すときに、Objective-C を読めるか聞かれたことがあります。
書けるまでは行かなくても読めるようにはなりたいです!
職務経歴書にも Objective-C を書けるようになりますしね!

あと、Swift はわかるけど Objective-C は分からないという人がこの記事を読んで「助かった〜」となってくれると嬉しいです☺️

対象者

  • Swift でアプリ開発をすると思っていたら、現場の言語に Objective-C が潜んでいて困っているエンジニア
  • Objective-C と Swift の書き方比較を見たい人

本題 (これだけ分かればええやろ?というとこだけ)

1. Objective-C にはファイルが2つある

Swiftだとファイル生成するときは、.swift ファイルだけ生成されますが、Objective-C では2つ生成されます。
.h ファイルと、 .m ファイルです。
現場の先輩に聞いた話だと、Objective-C は C言語を参考に作られた言語だからこうなってるらしいです。
C言語も、2つファイルが生成されるんでしょうね! (C++ が2つらしい)

 メモ 📝: 「〜.swift」 → 「〜.h」 と 「〜.m」 の2つになる

.h ファイル (ヘッダーファイル)

宣言をするファイルです。
プロパティや、メソッドを宣言します。中身は .m ファイルに書きます。

例えば、以下だけ書いている感じです。中身はないです。
Swift と Objective-C を書いてます。
※Swift にもし .h ファイルあったら、こんな感じでは?という書き方です。

Hoge.h(もしもSwiftで書いたら)
class Hoge: Fuga {
  let hoge: String 
  func getHoge() -> String {}
}
Hoge.h(Objective-C)
@interface Hoge: Fuga
- NSString hoge; 
- (NSString *)getHoge;
@end

※ NSStirng と String は違います。 が、わかりやすくするために書いてます!参考はこちら

.m ファイル (実装ファイル)

.m ファイルで中身を書いていきます!
変数の中身と、メソッドの中身ですね。
Swiftだったら一つのファイルなのに、Objective-C は .hファイル(宣言ファイル)も必要なんですね!

Hoge.m(Swiftならこう書く)
class Hoge: Fuga {
  let hoge: String = "test1"
  func getHoge() -> String {
      return hoge
  }
}
Hoge.m(Objective-C)
@interface Hoge: Fuga 
  NSString *hoge = @"test1"; 
  - (NSString *)getHoge {
     return self.hoge;
  }
@end

 メモ 📝: 独特な書き方だけど、 @interface~@end で囲まれていることと、;(セミコロン) で区切られていることを目印にすれば良さげ!

⭐️Tips⭐️

  • .h ファイルに書くのは他のファイルから参照できるようにするプロパティとメソッド。 .mファイルだけに書いたら、privateプロパティ、メソッドになる
  • プロパティに、@property をつけると、getter, setter が付与される
  • @interface~@end がクラスの宣言。
  • @interface~@end の後に、@implementation~@end を書くと、「クラスエクステンション」と呼ばれる機能を使える。クラスを拡張する機能。この機能を利用して疑似的にプライベートにすることが可能。(Swift の Extensionっぽい?)
  • import の対象は、 .h ファイルだけ。実装ファイルでなく、ヘッダーファイルを参照する。

2. メソッドの読み方がちと難しい

Objective-C では クラスのメソッドに - と + をつけます。
違いは、以下です。なるほど。

マイナス(ー)記号ではじまるものは「インスタンスメソッド」
クラスのインスタンスがあって初めて実行できるメソッド

プラス(+)記号で始まるのは「クラスメソッド」
クラスのインスタンスを生成せずに、クラスの型から直接実行することが可能で、クラスのインスタンスを生成して返すメソッドなどで使用されています。

メモ 📝: + は Swift の static メソッド

また、メソッドの引数や返り値の書き方が独特な気がします!
以下に、Swift と Objective-C のメソッドの使い方を記述します。
(String = NSString のニュアンスで書いてます)

Swiftのメソッドの基本形態
func メソッド名(引数1の内部の名前: 引数1の型, 引数2の外部の名前 引数2の内部の名前: 引数2の型) ->(返す型) {
   メソッドの中身
}

func getFuga(hoge: String, byPiyo receivePiyo: String) -> String {
   var fuga = hoge + receivePiyo
   return fuga
}

// 呼び出し方
getFuga(hoge: "引数hogeを渡すよ!", byPiyo: "これがPiyoだよ!")

Objective-Cのメソッドの基本形態
-(返す型)メソッド名:(引数1の型) 引数1の内部の名前 引数2の外部の名前:(引数2の型) 引数2の内部の名前 {
   メソッドの中身
}

- (NSString) getFuga: (NSString) hoge byPiyo: (NSString) receivePiyo {
   NSString *fuga = hoge + receivePiyo;
   return fuga;
} 

// 呼び出し方
[self getFuga:@"引数hogeを渡すよ!" byPiyo:@"これがPiyoだよ!"];

⭐️Tips⭐️

  • メソッドを呼び出すときは [ ] で囲まれている
  • メソッドの定義するときは、- か + が付く
  • : で、メソッド名と、引数が分かれている。引数が複数ある場合も、 :(コロン)で分かれている。

3. あとは雰囲気で読めそう(な気がする)

ざっと Objective-C で書かれたコードを見てみた感想は、
「意外と読めそう😈」です。

@privateや、@pubic,@protocol などなど、@~~ で書かれているものが何を示しているのかも、なんとなく読むことができると思いました。

自分が Objective-C を調査した結果、ファイルが2つに分かれている点と、メソッドの読み方さえできれば、なんとなく読むことはできる はずです。

データの型だったり、UIKit、NS~~の違いなどもあると思いますが、実際に Objective-C のコードに触れてみてキャッチアップしてみようと思います。

4. ハマったポイント(追記:2020/01/22)

NSString の比較は == ではできない

Swift なら String の比較で
if nameStr == "yamatatsu" {} でいけますが、objc はそんなことはできません。
isEqualToString というメソッドで比較します。

if ([nameStr isEqualToString:@"yamatatsu"])
{
    // Do stuff...
}

参考:nsstring - String comparison in Objective-C - Stack Overflow

print でログを出せない。

NSLogを使うみたいです。
print 便利だなぁ。。。

参考:NSLog - iPhoneアプリ開発の虎の巻

以下も重要👿

  • if文の条件は必ず () で囲む。
    • || を使いたい時は、 if (age == 17 || age == nil) {} のように使用する
  • メソッドは必ず [] で囲む。
  • セミコロンを忘れない ;

Objective-C を読むことができる諸先輩方へ

「Objective-Cのここは注意しな!」 だったり、「記事のここ全然違うよ。」 というところがあれば、ご教授いただければと思います!
よろしくお願いいたします🙇‍♂️

参考

Objective-Cまとめ @tomoyuki_okawa さん

Objective-C のメソッド定義の+(プラス)記号

Objective-Cのクラスやプロパティ、特徴的なメソッドの使い方 (3/3)

最後に

現場で読んでみた感想を編集後記として書こうと思います!
次回、「Objective-C を全然読めなかった話」 にならないように頑張ります😈

アプリ開発を始める方に読んでほしい記事↓↓↓↓↓↓

〜拝啓〜 アプリ開発を始める半年前の自分へ。アプリ公開初日に300ユーザーを獲得できるぞ!!!

編集後記

現場での読んでみた感想を書く予定😪

Objective-C 難しすぎです!!!
ただただSwiftが素晴らしいことに気づく日々。
これからSwift一択の現場にいくことを決意しました。

最高の記事があったのでシェア!!!
自分の記事の超上位互換!!!!
HACKING WITH SWIFT は素晴らしいな〜。
https://www.hackingwithswift.com/articles/114/objective-c-to-swift-conversion-cheat-sheet

yamatatsu10969
アプリ開発←金融系SE←爆発の研究 スキル:Flutter/Swift/Firebase/Kotlin 個人でアプリを開発しリリースしています!評価は今のところ4.9です! 今は Flutter に特に力を入れています。
https://oshidori-bbdb1.firebaseapp.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away