Object-C基礎-03-點語法

前言

在Java中,咱們能夠經過"對象名.成員變量名"來訪問對象的公共成員變量,這個就稱爲"點語法"。好比:java

1.在Student類的第2行定義了一個公共的成員變量age程序員

1 public class Student {
2     public int age;
3 }

2.而後在第5行經過點語法直接給stu的成員變量age賦值函數

public class Test {

    public static void main(String[] args) {
        Student stu = new Student();
        stu.age = 10;
    }

}

固然,正規的作法是讓成員變量私有化,讓外界使用公共的get方法和set方法訪問成員變量。學習

3.不少高級語言中都有這種點語法,爲了讓其餘行業的程序員快速上手OC,OC中也引入了點語法,只不過它的含義跟Java不太同樣this

1、傳統的get方法和set方法

在正式學習OC的點語法以前,先來看一下傳統的get方法和set方法。定義一個Student類,擁有一個成員變量age和對應的get\set方法。spa

1.Student.h

#import <Foundation/Foundation.h>

@interface Student : NSObject {
    int age;
}

- (void)setAge:(int)newAge;
- (int)age;

@end

1> 在第4行定義了一個成員變量age,是@protected權限的,因此外界不能直接訪問它code

2> 在第七、8行分別聲明瞭age變量的set方法和get方法orm

2.Student.m

#import "Student.h"

@implementation Student

- (void)setAge:(int)newAge {
    age = newAge;
}

- (int)age {
    return age;
}

@end

1> 在第5行實現了set方法對象

2> 在第9行實現了get方法ci

3.main.m

把定義好的Student類放到main函數中使用

#import <Foundation/Foundation.h>
#import "Student.h"

 int main(int argc, const char * argv[])
 {
   @autoreleasepool {
     Student *stu = [[Student alloc] init];
     
     // 設置age的值
     [stu setAge:10];
     
     // 取出age的值
     int age = [stu age];
     
     // 打印
     NSLog(@"age is %i", age);
     
       [stu release];
    }
    return 0;
 }


1> 在2行包含Student的頭文件

2> 在第7行建立Student對象,在第17行釋放Student對象

3> 在第10行調用set方法設置age的值

4> 在第13行調用get方法獲取age的值

5> 在第15行輸出age的值,輸出結果以下:

2013-04-08 00:26:19.002 點語法[6164:303] age is 10

這就是OC傳統的get方法和set方法的簡單使用,對初學者來講,這個語法比較奇怪,由於它的方法調用是用方括號[ ]完成的。所以,OC最終引入了點語法。

 

2、使用點語法代替傳統的get方法和set方法

上面演示了OC傳統get\set方法的簡單用法,接下來使用點語法來代替。

前面main.m中main函數的代碼能夠改成:

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Student *stu = [[Student alloc] init];
        
        // 設置age的值
        stu.age = 10; // 等價於[stu setAge:10];
        
        // 取出age的值
        int age = stu.age; // 等價於int age = [stu age];
        
        NSLog(@"age is %i", age);
        
        [stu release];
    }
    return 0;
}

1.注意第7行代碼,把原來的[stu setAge:10]替換成了stu.age = 10。聽清楚了,這兩種寫法是徹底等價的。即這裏的stu.age並不是表明直接訪問stu對象的成員變量age,而是編譯器遇到stu.age = 10的時候會自動將代碼展開成[stu setAge:10]

再說,若是是直接訪問成員變量的話,OC中應該是這樣的語法:stu->age,而不是stu.age。

2.注意第10行代碼,把原來的int age = [stu age]替換成了int age = stu.age。這兩種寫法又是徹底等價的,stu.age並不是直接訪問stu對象的成員變量age,而是編譯器遇到int age = stu.age的時候會自動將代碼展開成int age = [stu age]

3.所以,OC中點語法的含義跟Java是徹底不同的,OC點語法的本質是方法調用,不是直接訪問成員變量。至於這個點語法表明的是get方法仍是set方法,那就取決於你是取值仍是設值,取值就是get方法(如第10行代碼),設值就是set方法(如第7行代碼)。


4.若是你想驗證點語法是否是方法調用的話,有不少方法。

好比你能夠在Student.m的set方法和get方法內部用NSLog加一些打印信息,若是程序運行後有輸出打印信息,說明的確是調用了get方法或者set方法

#import "Student.h"

@implementation Student

- (void)setAge:(int)newAge {
    NSLog(@"調用了setAge方法");
    age = newAge;
}

- (int)age {
    NSLog(@"調用了age方法");
    return age;
}

@end

3、點語法和self的陷阱

1.在Java中,this關鍵字表明着方法調用者,也就是說,誰調用了這個方法,this就表明誰。因此通常會這樣寫set方法:

1 public void setAge(int newAge) {
2     this.age = newAge;
3 }

第2行表示將newAge參數的值,賦值給方法調用者的成員變量age


2.OC中有個self關鍵字,做用跟this關鍵字相似。我這麼說完,可能有人就會想這樣寫OC的set方法了:

1 - (void)setAge:(int)newAge {
2     self.age = newAge;
3 }

第2行中的self表明着當前調用setAge:方法的對象。可是第2行代碼是絕對錯誤的,會形成死循環。由於我在前面已經說過了,OC點語法的本質是方法調用,因此上面的代碼至關於:

1 - (void)setAge:(int)newAge {
2     [self setAge:newAge];
3 }

很明顯,會形成循環調用setAge:方法,程序就這樣崩潰了


4、一點小建議

若是是第一次接觸OC的點語法,你可能會真的覺得stu.age的意思是直接訪問stu對象的成員變量age。其實,有一部分緣由是由於我這裏定義的Student類的成員變量名就叫作age。爲了更好地區分點語法成員變量訪問,通常咱們定義的成員變量會如下劃線 _ 開頭。好比叫作 _age

1.Student.h,注意第4行

#import <Foundation/Foundation.h>

@interface Student : NSObject {
    int _age;
}

- (void)setAge:(int)newAge;
- (int)age;

@end

2.Student.m,注意第6行和第10行

#import "Student.h"

@implementation Student

- (void)setAge:(int)newAge {
    _age = newAge;
}

- (int)age {
    return _age;
}

@end


注:本文轉自M了個J博客。

相關文章
相關標籤/搜索