iPhone学習ノート1

8747 ワード

まずObjective-C言語を勉強したに違いない.Objective-C歴史なんてここで詳しく話さなくても、文法や使い方だけを話しましょう.
一、Objective-CとC++の違い
Objective-Cはc言語の厳格な親集合であり、任意のc言語プログラムがObjective-Cコンパイラを経ても変更する必要がないことを意味する.c++と異なり、c++はc言語と互換性のために設計されたオブジェクト向けの言語であり、ある意味ではc言語とは異なり、Objective-CはC言語に拡張を加えて創造されたオブジェクトの作成と操作が可能な新しいプログラム設計言語であり、gccはObjective-Cを原生的にサポートしている.
Objective-Cもmain関数から始まります.
int main(int argc, char *argv[]){
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
     NSLog(@"Hello World!");
     [pool drain];
return 0;}
Objective-Cの最大の特徴は、関数がメッセージを送信する形で動作し、クラスと関数の関係が緩やかで、関数を呼び出すと、そのクラスにメッセージを送信し、クラスが応答する保証がなく、応答できない場合は、プログラムは異常な方法で処理され、死ぬことはありません.c++は異なり,クラスとそのメソッドとの間にコンパイル中にすでに関連しており,そのクラス種が存在しないメソッドを呼び出すことは不可能である.Objective-Cは動的解析であるため,c++のvitural functionより3倍遅い速度であったが,imp速取改善により50%速くなった.
Objective-Cとc++の違いの一つは、Objective-Cが多重継承をサポートしていないことであり、javaと同様にプロトコルで解決される.Objective-Cには、特定の目的のために設定された「非公式プロトコル」と、コンパイラによって保証された「正式プロトコル」の2つのプロトコルがあります.
二、Objective-C文法
1、クラス
Objective-Cは、クラスをinterfaceとimplementationの2つのブロックに分割することを強制し、それぞれ@interface,@endと@implementation,@endでマークします.
次のようになります.
@interface MyObject : NSObject {
    int memberVar1;//メンバー変数
    id memberVar2;}
    +(return_type) class_method;//クラス関数はc++static関数に類似する
    -(return_type) instance_method1;//メンバー関数
    -(return_type) instance_method2: (int) p1;-(return_type) instance_method3: (int) p1 andPar: (int) p2;
@end
c++:
class MyObject : public NSObject {
    int memberVar1;
    void * memberVar2;
    public: static return_type class_method();
    return_type instance_method1();
    return_type instance_method2( int p1 );
    return_type instance_method3( int p1, int p2 );
}
実行ブロック:
@implementation MyObject
+(return_type) class_method {
....//method implementation
}
-(return_type) instance_method1 {
....
}
-(return_type) instance_method2: (int) p1 {
....
}
-(return_type) instance_method3: (int) p1 andPar: (int) p2 {
....
}
@end
通常inerfaceに入れる.hファイル.ブロックの挿入を実行します.mファイルは、c++のようにcppファイルでの使用クラス名に::シンボルを付けてクラス関数を外部化する方法です.
クラスオブジェクトの作成方法:
(1)MyObject*my=[[MyObject alloc]init];//allocはメモリ割り当て空間であり、initはc++のconstructor関数のように書き換えられ、初期化を実現することができる.
(2)MyObject * my = [MyObject new];           //Objective-C2.0
クラスメソッド呼び出し:
以上から、「クラス名(またはクラスオブジェクト名)クラスメソッド(またはクラスメンバー関数)」であることがわかります.
2、協議
正式なプロトコルはJavaのインタフェースに似ています.これは一連のメソッドのリストであり、どのクラスも1つまたはいくつかのプロトコルが実装されたことを宣言することができます.Objective-C 2.0の前に、クラスが一致するプロトコルを宣言するすべてのメソッドを実装する必要があります.そうしないと、コンパイラは、一致するプロトコルを宣言するすべてのメソッドを実装していないことを示すエラーを報告します.Objective-C 2.0のバージョンでは、タグプロトコルのいくつかの方法がオプションであることを許可し、コンパイラはこれらのオプションの方法を強制的に実現しません.
非公式プロトコルは、クラスが選択的に実装できる一連のメソッドのリストである.
構文
@protocol Locking
- (void)lock;- (void)unlock;
@end
「鍵」の抽象観念があることを示している.以下の声明は、このクラスがプロトコルLockingを実装していることを示しています.
@interface SomeClass : SomeSuperClass
@end
3、ダイナミックタイプ
- setMyValue:(id) foo; この関数は、任意のクラスインスタンスにメッセージを送信できます.
- setMyValue:(id ) foo; この宣言は、fooが任意のクラスのインスタンスであってもよいことを示していますが、aProtocolプロトコルに準拠する必要があります.
- setMyValue:(NSNumber*) foo; この宣言は、「foo」が「NSNumber」のインスタンスである必要があることを示しています.
静的タイプ情報は、コンパイル中にチェックされる変数にも適用できます.以上の3つの宣言は、より明らかなタイプの情報を提供しています.この3つの宣言は、実行時に同等ですが、追加のタイプ情報により、コンパイラがコンパイル時に変数タイプをチェックし、タイプが一致しない場合に警告を出すことができます.
4、転送
  • 転送方法:
    - (retval_t) forward:(SEL) sel :(arglist_t) args; // with GCC
    - (id) forward:(SEL) sel :(marg_list) args; // with NeXT/Apple systems
    

  • 応答方法:
    - (retval_t) performv:(SEL) sel :(arglist_t) args;  // with GCC
    - (id) performv:(SEL) sel :(marg_list) args; // with NeXT/Apple systems
    


  • forwardメソッドの書き換え

    ここでは、転送の基本概念を示すプログラムの例を示す.
    Forwarder.h
    #import
    @interface Forwarder : Object{
         id recipient;//このオブジェクトは私たちが転送したいオブジェクトです.
    }
    @property (assign, nonatomic) id recipient;
    @end
    Forwarder.m
    #import "Forwarder.h"
    @implementation Forwarder
    @synthesize recipient;
    -(retval_t)forward:(SEL)sel:(arglist_t)args{/**転送対象が該当メッセージを鳴らすかどうかをチェックします.*転送対象が該当メッセージを鳴らさないと転送されずエラーが発生します.*/
        if([recipient respondsTo:sel])
        return [recipient performv: sel : args];
         else return [self error:"Recipient does not respond"];
    }
    Recipient.h
    #import
    //A simple Recipient object.
    @interface Recipient : Object
    - (id) hello;
    @end
    Recipient.m
    #import "Recipient.h"
    @implementation Recipient
    - (id) hello{
        printf("Recipient says hello!");
        return self;
    }
    @end
    main.m
    #import "Forwarder.h"
    #import "Recipient.h"
    int main(void){
    Forwarder *forwarder = [Forwarder new];
    Recipient *recipient = [Recipient new];
    forwarder.recipient = recipient;
    //Set the recipient./* *転送者はhelloメッセージに応答しません!このメッセージは転送対象に転送されます.*(転送対象が該当メッセージを鳴らす場合)*/
    [forwarder hello];
    return 0;
    }
    5、カテゴリ
    クラスファイルを新規作成hとArithmetic.m
    @interface Integer (Arithmetic)
    ...
    @end
    および
    @implementation Integer (Arithmetic)
    ...
    @end
    実行体の関数は、使用したい場合はhファイルをimportし、使用したくない場合は簡単にファイルをコンパイルしなくてもよい.
    コマンド:gcc-x objective-c main.m Integer.m Arithmetic.m Display.m -lobjc
    この機能を使用しています.
    6、属性
    Objective-C 2.0は、変数を宣言する属性として新しい構文を導入しました.
    構文の定義:
    @interface Person : NSObject {
    @public
        NSString *name;
    @private
        int age;
    }
    @property(copy) NSString *name;
    @property(readonly) int age;
    -(id)initWithAge:(int)age;
    @end
    属性のアクセスメソッドは@synthesizeキーワードによって実現され、属性の宣言によって自動的に一対のアクセスメソッドが生成されます.また、@dynamicキーワードを使用して、アクセス方法がプログラマによって手動で提供されることを示すこともできます.
    @implementation Person
    @synthesize name;
    @dynamic age;
    -(id)initWithAge:(int)initAge{
        age = initAge;//注:属性ではなくメンバー変数に直接割り当てられます.
        return self;
    }
    -(int)age{
        return 29; //注意:本当の年齢に戻るわけではありません
    }
    @end変数のみ定義されている場合
    NSString
    *name、@propertyなし..nameはselfを用いる.nameはコンパイルできません.@propertyのみを定義します...name、nameを使用するとコンパイルが通過せず、nameは定義されず、selfを使用する場合.nameはコンパイル可能であるがselfを用いる.nameは直接異常を投げ、プログラムは終了します.@propertyが定義されています...name、および@synthesizeは、nameを直接呼び出すのに問題はありませんがselfを使用します.nameはプログラムを直接終了させる.変数と@property,@synthesizeを同時に定義すると、直接変数を呼び出すのとselfを使用して変数を呼び出すのと同じ効果があります.
    7、ゴミ回収
    gccオープンごみ収集のパラメータは-fobjc-gc
    しかし、iphoneはゴミ収集をサポートしていません.また、効率が低下するに違いないので、古いカウント方式で手作業で回収したほうがいいです.
    8、快速列挙
    //NSEnumeratorの使用
    NSEnumerator *enumerator = [thePeople objectEnumerator];
    Person *p;
    while ( (p = [enumerator nextObject]) != nil ) {
        NSLog(@"%@ is %i years old.",[p name], [p age]);
    }
    //逐次列挙の使用
    for ( int i = 0; i < [thePeople count]; i++ ) {
        Person *p = [thePeople objectAtIndex:i];
        NSLog(@"%@ is %i years old.", [p name], [p age]);
    }
    //クイック列挙の使用
    for (Person *p in thePeople) {
        NSLog(@"%@ is %i years old.", [p name], [p age]);
    }高速列挙は、列挙によって呼び出される方法がNSFastEnumerationプロトコルによって提供されるポインタ演算によって置き換えられるため、標準列挙よりも効率的なコードを生成することができる.効率は違います.
    参考資料:
    http://zh.wikipedia.org/wiki/Objective-C#.E5.8A.A8.E6.80.81.E7.B1.BB.E5.9E.8B