OC 語法快速入門

來源: https://www.runoob.com/w3cnot...html

Interface

定義部分,清楚定義了類的名稱、數據成員和方法。 以關鍵字@interface做爲開始,@end做爲結束。程序員

@interface MyObject : NSObject {
    int memberVar1; // 實體變量
    id  memberVar2;
}

+(return_type) class_method; // 類方法

-(return_type) instance_method1; // 實例方法
-(return_type) instance_method2: (int) p1;
-(return_type) instance_method3: (int) p1 andPar: (int) p2;
@end

方法前面的 +/- 號表明函數的類型:加號(+)表明類方法(class method),不須要實例就能夠調用,與C++ 的靜態函數(static member function)類似。減號(-)便是通常的實例方法(instance method)。objective-c

這裏提供了一份意義相近的C++語法對照,以下:編程

class MyObject : public NSObject {
protected:
    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 );
}

Objective-C定義一個新的方法時,名稱內的冒號(:)表明參數傳遞,不一樣於C語言以數學函數的括號來傳遞參數。Objective-C方法使得參數能夠夾雜於名稱中間,沒必要所有附綴於方法名稱的尾端,能夠提升程序可讀性。設定顏色RGB值的方法爲例:多線程

- (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue; /* 宣告方法*/

[myColor setColorToRed: 1.0 Green: 0.8 Blue: 0.2]; /* 呼叫方法*/

這個方法的簽名是setColorToRed:Green:Blue:。每一個冒號後面都帶着一個float類別的參數,分別表明紅,綠,藍三色。函數

在Object-C中,有兩種類型的方法,類方法和實例方法。性能

類方法以+開頭,其基本形式以下:this

(id)someMethod;atom

類方法通常都是工廠方法,返回一個實例。線程

實例方法以-開頭,其基本形式以下:

- (void)someMethod;

方法能夠不帶參數,也能夠帶一個或多個參數,也能夠有返回值:

(int)someMethod;

(void)someMethodWithValue:(SomeType)value;

(void)someMethodWithFirstValue:(SomeType)value1 secondValue:(AnotherType)value2;

一、程序的頭文件和源文件的擴展名分別爲.h 和.m;

二、註釋:單行(//)和多行(/* … */);

三、Object_C 中的nil 至關於NULL。

四、Object_C 中的YES 和NO 至關於true 和false。

五、#import至關於#include ,導入頭文件也有兩種查找方式< … > 和" … ",可是#import 可自動防止同一個文件被導入屢次。

六、Object_C中的全部類都必須繼承自NSObject。

七、Object_C僅支持單一父類繼承,不支持多重繼承。

八、Object_C中全部對象都是指針的形式。

九、Object_C用self代替this。

十、Object_C使用id代替void*。

十一、Object_C中用消息表示類的方法,並採用[aInstance method:argv]調用形式。

十二、Object_C支持反射機制。

1三、Object_C支持Dynamic Typing,Dynamic Binding和Dynamic Loading。

Implementation

實現區塊則包含了公開方法的實現,以及定義私有(private)變量及方法。 以關鍵字@implementation做爲區塊起頭,@end結尾。

@implementation MyObject {
  int memberVar3; //私有實體變數
}

+(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

屬性

屬性是用來代替聲明存取方法的便捷方式。屬性不會在你的類聲明中建立一個新的實例變量。他們僅僅是定義方法訪問已有的實例變量的速記方式而已。暴露實例變量的類,可使用屬性記號代替getter和setter語法。類還可使用屬性暴露一些「虛擬」的實例變量,他們是部分數據動態計算的結果,而不是確實保存在實例變量內的。

實際上能夠說,屬性節約了你必需要寫的大量多餘的代碼。由於大多數存取方法都是用相似的方式實現的,屬性避免了爲類暴露的每一個實例變量提供不一樣的getter和setter的需求。取而代之的是,你用屬性聲明指定你但願的行爲,而後在編譯期間合成基於聲明的實際的getter和setter方法。

屬性聲明應該放在類接口的方法聲明那裏。基本的定義使用@property編譯選項,緊跟着類型信息和屬性的名字。你還能夠用定製選項對屬性進行配置,這決定了存取方法的行爲。下面的例子展現了一些簡單的屬性聲明:

@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

屬性能夠利用傳統的消息表達式、點表達式或"valueForKey:"/"setValue:forKey:"方法對來訪問。

Person *aPerson = [[Person alloc] initWithAge: 53];
aPerson.name = @"Steve"; // 注意:點表達式,等於[aPerson setName: @"Steve"];
NSLog(@"Access by message (%@), dot notation(%@), property name(%@) and direct instance variable access (%@)",
      [aPerson name], aPerson.name, [aPerson valueForKey:@"name"], aPerson->name);

爲了利用點表達式來訪問實例的屬性,須要使用"self"關鍵字:

-(void) introduceMyselfWithProperties:(BOOL)useGetter
{
    NSLog(@"Hi, my name is %@.", (useGetter ? self.name : name)); // NOTE: getter vs. ivar access
}

類或協議的屬性能夠被動態的讀取。

多個屬性之間,可使用逗號分隔:

@property (strong, nonatomic) UIWindow *window; 屬性一般還會加一些修飾,來控制數據的訪問和存儲等:

@property (readonly) NSString *firstName;
@property (readonly) NSString *lastName;

屬性修飾:

readonly與readwrite:

readonly代表該屬性是隻讀的,外部不能修改其值。與readonly相對的修飾是readwrite,但你沒必要把它寫出來,由於它是默認的。 atomic與nonatomic:

(atomic、nonatomic)屬性用於多線程編程,屬性默認是atomic的。在多線程環境下設置爲atomic能夠保證數據讀取的一致性(由於,它將保證數據僅僅被一個線程獨佔。也就是說一個線程進行寫操做時,將鎖定該屬性,不容許其餘的線程進行寫操做。)因爲該操做會對數據進行鎖操做,故會消耗較多的資源。因此在不須要進行多線程操做時建議將該屬性設置爲nonatomic,設置爲該參數時程序在任何狀況都不會鎖定該屬性。

strong與weak:

其中strong是默認的。strong表示該屬性對其相應的對象是強引用。一個變量保持對一個對象的強引用,只要該變量在其做用域範圍內或者直到它被賦給另外一個對象或者nil爲止。weak表示對屬性對應的對象的弱引用。

copy、assign、retain:

copy修飾表示該屬性將使用強引用,由於它必須保持它建立的新對象。

assign指定setter方法用簡單的賦值,不更改索引計數(Reference Counting),通常對簡單數據類型 使用assign。

retain,對象引用計數加一。

快速枚舉

比起利用NSEnumerator對象或在集合中依次枚舉,Objective-C 2.0提供了快速枚舉的語法。在Objective-C 2.0中,如下循環的功能是相等的,但性能特性不一樣。

// 使用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協議提供的指針算術運算所代替了。

還有一些其餘的好比類別,轉發 這些都是後面再學也不要緊的

相關文章
相關標籤/搜索