LoginSignup
58
55

More than 5 years have passed since last update.

Objective-Cまとめ

Last updated at Posted at 2014-07-04

はじめに

Objective-CはJavaよりも古くからあり、最近ではSwiftという言語でもiOSアプリを開発が可能となりました。
ですが、既存アプリの改修や、Objective-Cを使わなければならない場面もあるため、
習熟はObjective-Cから入った方が良いと思います。

このメモの目的と注意点

私はもともとASPからプログラミングを学び、業務では主にJavaを使用していました。
現在はWEBエンジニアとしていろいろ言語には触りますが、知識としてはかなりJavaよりだと自負しています。
後輩や、新人がこれからiOSアプリを制作するにあたって、先ず読んでもらいたいと思う情報をまとめよう!
という事でこのメモを作成しています。
少しでもそういう方の役に立てればと思い、投稿します。が、書きかけです。
のんびり書いていこうと思います。

Xcodeについて

XcodeとはAppleが提供してくれているIDE(統合開発環境)です。
Objective-CのコンパイルからApple Store申請、ipaファイル書き出しなど、
様々なサポートを行ってくれるソフトウェアです。
現在、XcodeがWindows上で動作しないため、Macでの開発が必須となっています。

Xcodeは現在3つのバージョンがあります。
Xcode4.6.3 Xcode5.x Xcode6 beta の3種類です。
新規アプリの開発などには Xcode5.x (現行の最新安定版) を利用します。
Xcode4.6.3 環境で作成したアプリに関しては Appleによりリジェクト対象となっています。
(すなわち、申請する必要のないアプリに関しては4.6.3でも構わないという事でもあります。)

Xcode6 beta は文字通りβバージョンではあります。
2014年秋にiOS8と同時期にリリース予定であり、リリース後はXcode6を利用することになるでしょう。
(AppleがそのうちXcode5でビルドしたアプリをリジェクト対象にしてしまうため。)

Xcode4.6.3について

現在の最新である OS X 10.9.3 では動作しません。
OS X 10.9.3未満 を所持している方は極力アップデートを避けましょう。

構文

コンパイラはCと同じ

gccコマンドでコンパイルできます。(Xcodeがやってくれるので意識しなくても良いですが)
C言語に触ったことのない人で、最も理解に苦しむのはポインタ(*)だと思われます。

@ ではじまる構文

これらはコンパイラディレクティブと呼ばれるものになります。

宣言とか

@interface @implementation @protocol @end

インスタンス変数のスコープ

@private @protected @public

例外処理

@try @throw @catch @finally

その他

@class @selecter() @protocol() @encode() @defs() @"文字列" @synchronized

宣言

クラスの定義

下記の例では setNumber getNumber というアクセサを実装していますが、
実際には @property@synthesize を利用している場合、以下の様な実装は必要ありません。

class.h
@interface SampleClass : SuperSampleClass <SampleProtocol>

@property (retain, nonatomic) int number;

- (int)getNumber;
- (void)setNumber:(int)value;
@end
class.m
@implementation SampleClass

@synthesize number;

- (int)getNumber {
    return self.number;
}
- (void)setNumber:(int)value {
    self.number = value;
}
@end

Objective-cはC言語と同じく、2ファイルで構成されています。
ヘッダーファイル(拡張子:h)とメインファイル(拡張子:m)で、ヘッダーファイルは主に定義を記述し、
実装部分はメインファイルに記述します。

  • @interface クラス名 : 継承するクラス名 < 採用するプロトコル >

プロトコルについては後述します。

プロパティ
  • @property ( 属性 ) (IBOutlet) プロパティの型 プロパティの名前
属性
属性 意味
readonly 読み取り専用。ゲッタメソッドのみ生成
readwrite 読み書き可能(デフォルト。省略可)セッタメソッド、ゲッタメソッド共に生成
copy 引数の値をコピーして渡す
atomic インスタンスの同時実行をさせない。が怪しい(デフォルト、省略可)
nonatomic 基本的にatomicは指定せずにこちらを指定し、インスタンスの同時実行をさせない場合は別途処理を記述する必要がありそう
assign retainを実行しないで単純に代入する(ARCの__unsafe_unretainedと同じ意)
getter= ゲッタメソッド名を変えたい場合
setter= セッタメソッド名を変えたい場合(引数がつくため、最後に:(コロン)が必要)
strong ARCの強い参照と同じ意
retain ARCの強い参照と同じ意
__weak ARCの弱い参照と同じ意

assign, retain, copy でアクセサを合成した場合は、それぞれ下記の様な実装になる。

// assign 
property = newValue; 

// retain 
if (property != newValue) { 
    [property release]; 
    property = [newValue retain]; 
}

// copy 
if (property != newValue) { 
    [property release]; 
    property = [newValue copy]; 
} 
IBoutletとは

IBOutletを宣言し、InterfaceBuilderと接続したプロパティ(またはインスタンス変数)は、
初期化の際に接続したインスタンスを初期化の段階で設定してくれます。

プロパティとインスタンス変数について

この辺は自分で調べてみてください。
プロパティを上記方法で記述すると、インスタンス変数も生成されます。

スコープ

インスタンス変数を定義する場合は、スコープを設定可能です。
スコープとは可視範囲という意味で、3つの種類が用意されています。

  • private
  • protected
  • public
private

privateとは、定義したクラスでしか扱う事ができません。
インスタンス化した際はもちろん、定義したクラスを継承した場合でも、privateで宣言したものは参照できません。

protected

protectedは、privateから少し範囲が広くなり、定義したクラスを継承したクラスで参照できるようになります。
この継承には制限がなく、子でも孫でも、それ以下でも参照可能となります。

public

さらに範囲が広がり、publicにはスコープによる可視範囲の制限がなくなります。

プロパティは確はprivateだった気がします。
が、アクセサメソッドが自動生成されるので、あんまり気にしなくても構いません。
(実装部に @synthesize を設定した場合)

メソッド
  • ( 戻り値の型 ) メソッド名 :( 引数の型 ) 引数の変数名

メソッドは上記の様に記述します。
戻り値を省略する場合は、戻り値の型を void と設定します。

クラスメソッドとインスタンスメソッド

クラスメソッドとインスタンスメソッドは、メソッド定義の先頭で指定します。

先頭 意味
+ クラスメソッド
- インスタンスメソッド
引数の数による違い

Objective-Cのメソッドは他の言語ではあまり指定しない、引数のラベルを指定します。
これは引数が2個以上の場合に指定します。

引数が無い場合
// メソッドの定義
- (void)countUp;

// メソッドの実行
[self countUp];
引数が1つの場合
// メソッドの定義
- (void)countUp:(int)value;

// メソッドの実行
[self countUp:1];
引数が2つの場合
// メソッドの定義
- (void)countUp:(int)value max:(int)maxValue;

// メソッドの実行
[self countUp:1 max:10];

プロトコルの定義

プロトコルとは メソッドのみを定義したもの となります。
プロトコルはクラスではありませんので、オブジェクトはなく、もちろんインスタンス化もできません。
したがってプロトコルはヘッダーファイルのみ存在します。

プロトコルの用途は、クラスに対して必要なメソッドを定義しておき
クラスで採用して使用します。
例)
プロトコル名:電話プロトコル
所持機能  :音声の送信、音声の受信
この様なプロトコルを定義し、実際に電話機としてのクラスを作成する場合、
このプロトコルを採用します。
そうすることによって、電話プロトコルを採用しているクラスは最低限、
上記で定義した機能を所持しているという状態が保証されます。
型を指定して使用はできないが、機能のみを特定して処理を行いたい場合、
id<TelProtocol> の様にプロトコルを指定してやることで、id 型のまま定義した機能を利用する事が可能となります。

protocol.h
@protocol ProtocolName
- (void)requiredMethod;

@required
- (void)requiredMethodTwo;

@optional
- (void)otherMethod;

@end

プロトコルは継承することも可能です。

protocol.h
@protocol ChildProtocol <SuperProtocol>
@end

プロトコルとは、Javaではインターフェイスと呼ばれています。
Javaではインターフェイスは実装して利用していましたが、
Objective-Cでは 採用する と呼ぶそうです。

@interface Class <ChildProtocol>

// 複数のプロトコルを採用剃る場合
@interface Class <ChildProtocol, OtherProtocol>

ステートメント

データ型

データ型 意味
int 32ビット 符号付き整数型
unsigned int 32ビット 符号なし整数型
long 32ビット 符号付き整数型
unsigned long 32ビット 符号なし整数型
short 16ビット 符号付き整数型
unsigned short 16ビット 符号なし整数型
char 8ビット 符号付き整数型(1文字を格納)
unsigned char 8ビット 符号なし整数型(1文字を格納)
float 32ビット 浮動小数点数型
double 64ビット 浮動小数点数型
BOOL 真偽値型(YES or NO)
NSInteger 32ビット 符号付き整数型
NSUInteger 32ビット 符号なし整数型
NSDecimal 160ビット 浮動小数点数型

上記以外は基本的に参照型となります。

long, NSInteger, CGFloatなどは64ビット向けにコンパイルすると64bit長になりますので注意が必要です。
参考:http://d.hatena.ne.jp/nakamura001/20130929/1380450561

変数の宣言

変数の宣言は特殊なところはありません。

  • 変数名
宣言
int age;
NSString* name;
NSString *address;
NSString * girlFriendName;
id child;

id が汎用オブジェクトでも言いましょうか、どのクラスでも収容できる型となります。
参照型を宣言する場合は上記の様にアスタリスク(*)を付けなければいけません。
id 型には必要ありません。
(型、変数名のどちらかにつけるかは好き好きみたいです。たぶん。)

分岐

条件については、他言語とそんなに違いはありません。
a == b a != b a && b a || b !a どれも使えます。

if構文
// 基本構文
if (a == 1) {
    // a == 1 が成立した際の処理
}

// 分岐
if (a == 1) {
    // a == 1 が成立した際の処理
}
else if (a == 2) {
    // a == 1 が成立せず、a == 2 が成立した際の処理
}
else {
    // a == 1 が成立せず、a == 2 も成立しなかった際の処理
}

// 三項演算子
// a == 1 が成立した場合は one が、しなかった場合は other が代入される
NSString *str = (a == 1) ? @"one": @"other";
switch構文
switch(integer){
  case 1:
    // integer == 1 が成立した際の処理
    break;

  case 2:
    // integer == 2 が成立した際の処理
    break;

  default:
    // 上記の処理をbreakで抜けない限り、常に処理
    break;
}

ループ

continue break 共に以下のステートメントで利用できます。

for構文
// i を 0 から 9 まで 10回 ループさせる
for(int i = 0; i < 10; i+){
    // 処理
}

// コレクションのループも用意されています
NSArray *array;
for(NSString *str in array){
    // 処理
}
while構文
while (a == 1) {
  // a == 1 が成立する間、常に処理
}

// do-while構文
do {
  // a == 1 が成立する間、常に処理されるが、初回は必ず処理する
} while (a == 1);

ブロック構文

書きかけです!

58
55
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
58
55