1. 程式人生 > >【黑馬程式設計師】Objective-C語言學習筆記之核心語法(四)

【黑馬程式設計師】Objective-C語言學習筆記之核心語法(四)

--------------------------------------------IOS期待與您交流!--------------------------------------------

一、點語法

1、沒有使用點語法的情況

此時我們使用setter和getter方法來訪問物件的成員變數
#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    int _age;
}
- (void)setAge:(int)age;
- (int)age;
@end

@implementation Person

- (void)setAge:(int)age
{
    NSLog(@"呼叫了setAge方法");
    _age = age;
}

- (int)age
{
    NSLog(@"呼叫了age方法");
    return _age;
}
@end

int main()
{
    // 沒有使用點語法的時候
    Person *p = [Person new];
    [p setAge:20];
    int age = [p age];
    NSLog(@"年齡是:%d", age);
    return 0;
}
輸出結果:

2014-03-19 20:15:13.476 Test[470:303]呼叫了setAge方法

2014-03-19 20:15:13.477 Test[470:303]呼叫了age方法

2014-03-19 20:15:13.478 Test[470:303]年齡是:20

2、使用了點語法的情況

使程式碼更簡潔了,本質是方法呼叫
#import <Foundation/Foundation.h>

// Person方法的宣告和實現和上面一樣

int main()
{
    // 使用點語法的時候
    Person *p = [Person new];
    p.age = 20; // 本質是 -> [p setAge:20];
int age = p.age; // 本質是 -> int age = [p age]; NSLog(@"年齡是:%d", age); return 0; }
輸出結果:

2014-03-19 20:15:13.476 Test[470:303] 呼叫了setAge方法

2014-03-19 20:15:13.477 Test[470:303] 呼叫了age方法

2014-03-19 20:15:13.478 Test[470:303] 年齡是:20

3、注意

- (void)setAge:(int)age
{
    // 相當於 [self setAge:age],會引發死迴圈
    self.age = age;
}

- (int)age
{
    // 相當於 [self age],會引發死迴圈
    return self.age;
}

二、成員變數的作用域

public:在任何地方都能直接訪問物件的成員變數
protected:可在當前類及其子類物件中直接訪問物件的成員變數(預設的)
private:只能在當前類中直接訪問物件的成員變數
package:同一框架中能直接訪問物件的成員變數

三、@property和@synthesize

1、以前的程式碼方式

@interface Person : NSObject
{
    int _age;
}
- (void)setAge:(int)age;
- (int)age;
@end

@implementation Person

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

- (int)age
{
    return _age;
}
@end

2、使用了@property和@synthesize

下面程式碼和上面是等效的
@interface Person : NSObject
@property int age;
@end

@implementation Person
@synthesize age = _age;
@end

3、只使用了@property

下面程式碼和上面是等效的
@interface Person : NSObject
@property int age;
@end

@implementation Person
@end

4、總結

1-> 只用@property時,會產生3個效果(以@property int 為例)
    1 生成 _age 成員變數(private的成員變數)
    2 生成 age 的 setter 和 getter 方法的宣告
    3 生成 age 的 setter 和 getter 方法的宣告
2-> 使用@property和@synthesize時,和上面的效果基本相同,不同在於@synthesize可以指定生成的成員變數的名稱。

@interface Person : NSObject
@property int age;
@end

@implementation Person
@synthesize age = hello;
@end
就會等價於
@interface Person : NSObject
{
    int hello;
}
- (void)setAge:(int)age;
- (int)age;
@end

@implementation Person

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

- (int)age
{
    return hello;
}
@end
使用@synthesize時,推薦使用_age,這樣更符合約定

5、此外

只有使用了@property ,才會自動生成private的_age。使用@synthesize 用來改變@property 生成的成員變數名。
如果自己只實現了setter 方法,會自動生成getter 方法和帶下劃線的成員變數(_age)
如果自己只實現了getter 方法,會自動生成setter 方法和帶下劃線的成員變數(_age)
如果自己實現了setter 方法和getter 方法,就不會自動生成成員變數(_age),需要我們手動生成

四、構造方法(init)

1、new方法

我們可以通過new 方法來生成一個物件
Person *p = [Person new];
其實new 是分兩步來生成物件的
* 呼叫+alloc 方法來給物件分配記憶體空間
* 呼叫-init 方法給物件的成員變數初始化成預設的值
缺點:不能在建立物件的同時進行一些必要的初始化

2、alloc 和 init 方法

重寫構造方法的目的:為了讓物件一創建出來,成員變數就由一些預設的值
@interface Person : NSObject
@property int age;
@end

@implementation Person
// 需要重寫init 方法來滿足自己的初始化要求
- (id)init
{
    // 必須先呼叫父類的構造方法對父類的變數進行初始化
    if (self = [super init]) {
        _age = 20;
    }
    return self;
}
@end

int main()
{
    Person *p = [[Person alloc] init];  // 和 Person *p = [Person new]; 一樣的效果
    NSLog(@"年齡是:%d", p.age);
    return 0;
}
輸出:

2014-03-19 21:20:29.860 Test[644:303]年齡是:20

3、自定義init 方法(自定義構造方法)

@interface Person : NSObject
@property int age;
@end

@implementation Person
- (id)initWithAge:(int)age
{
    if (self = [super init]) {
        _age = age;
    }
    return self;
}
@end

int main()
{
    Person *p = [[Person alloc] initWithAge:24];  
    NSLog(@"年齡是:%d", p.age);
    return 0;
}
輸出:

2014-03-19 21:25:55.821 Test[656:303]年齡是:24

五、分類(Category)

作用:在不改變類的基礎上增加一些方法
類名:類名 (分類名)
分類名一般是模組名
如想為Person類增加一個新增一個分類LXZ
Person+LXZ.h
#import "Person.h"

@interface Person (LXZ)
- (void)study;
@end
Person+LXZ.m
#import "Person+LXZ.h"

@implementation Person (LXZ)
- (void)study
{
    NSLog(@"lxz study");
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Person+LXZ.h"

int main()
{
    Person *p = [[Person alloc] init];  
    [p study];
    return 0;
}
輸出:

2014-03-19 21:58:17.997 OCTest[841:303] lxz study

注意
 1 分類只能增加方法,不能增加成員變數
 2 分類方法中可以訪問原來類中的成員變數
 3 分類可以重新實現原來類中得方法,這會覆蓋原來類中的方法,使原來類中的方法失效
 4 方法呼叫優先順序:分類(最後被編譯的分類) -> 原來類

六、SEL

在OC中,物件或類每當呼叫一個方法時,會把方法包裝成一個SEL的資料型別,然後去類物件中找對應的SEL(類物件中有該類的所有方法的SEL,每個方法對應一個SEL)。若找到,則呼叫相應的方法,若沒找到,則報錯。
以上面的 Person 類為例,看看呼叫age的getter方法的方式有哪些
方式一(隱式的使用了SEL)
[p age];
方式二(顯式的使用了SEL)
[p performSelector:@selector(age)];
方式三(顯示的使用了SEL)
SEL sel = NSSelectorFromString(@"age");
[p performSelector:sel];








--------------------------------------------IOS期待與您交流!--------------------------------------------

相關推薦

黑馬程式設計師Objective-C語言學習筆記核心語法

--------------------------------------------IOS期待與您交流!-------------------------------------------- 一、點語法 1、沒有使用點語法的情況 此時我們使用setter和gette

黑馬程式設計師Objective-C語言學習筆記物件的建立、使用和方法呼叫

--------------------------------------------IOS期待與您交流!-------------------------------------------- 一、物件的建立 物件是由類建立,我們使用上一文章用到的類來建立物件。 說明:

黑馬程式設計師Objective-C語言學習筆記之類

--------------------------------------------IOS期待與您交流!-------------------------------------------- 一、OC中類的組成 OC中類一般由宣告和實現組成。 類的宣告:儲存在.h檔案

黑馬程式設計師分散式事務TransactionScope(學習筆記)

分散式事務: btnDel_Click() {  Delete(1);  Delete(2); } 如果 Delete(1)執行後Delete(2)沒有執行的話;  銀行轉賬 回滾 是資料庫的原子性 事務(Transaction) 1.TransactionScope採用

黑馬程式設計師C語言基礎-指標

------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、

黑馬程式設計師棧記憶體與堆記憶體

java中記憶體分配策略及堆和棧的比較    1 記憶體分配策略    按照編譯原理的觀點,程式執行時的記憶體分配有三種策略,分別是靜態的,棧式的,和堆式的.    靜態儲存分配是指在編譯時就能確定每個資料目標在執行時刻的儲存空間需求,因而在編譯時就可以給他們分配固定的記憶體空間.這種分配策略要求程式程式碼中

黑馬程式設計師7k面試題交通燈

 交通燈專案需求: 模擬實現十字路口的交通燈管理系統邏輯,具體需求如下:         非同步隨機生成按照各個路線行駛的車輛。 例如:        由南向而來去往北向的車輛 ---- 直行車輛        由西向而來去往南向的車輛 ---- 右轉車輛       

黑馬程式設計師7K面試題銀行排程系統

模擬實現銀行業務排程系統邏輯,具體需求如下: Ø        銀行內有6個業務視窗,1- 4號視窗為普通視窗,5號視窗為快速視窗,6號視窗為VIP視窗。 Ø        有三種對應型別的客戶:VIP客戶,普通客戶,快速客戶(辦理如交水電費、電話費之類業務的客戶)。

黑馬程式設計師關於try和fianlly中的return執行問題總結

---------------------- ASP.Net+Android+IOS開發、.Net培訓、期待與您交流! ---------------------- 我們都知道finally語句塊的作用是無論出現什麼情況,finally塊中的語句一定會被執行,並且是在re

objective-c語言學習筆記

1、c語言風格函式申明 int add(int a, int b);     oc語言為 (int)add:(int)a par2:(int) b; 函式名add也是第一個引數名稱,第二個引數名稱是par2,這樣處理是為了實現函式的多型性。  

梓益C語言學習筆記常用鏈表操作函數

C語言 鏈表操作 梓益C語言學習筆記之常用鏈表操作函數一、創建鏈表void link_creat_head(STU **p_head,STU *p_new){ STU *p_mov=*p_head; if(*p_head==NULL) //當第一次加入鏈表為空時,head執行p_new { *

梓益C語言學習筆記鏈表&動態內存&文件

C語言 鏈表 梓益C語言學習筆記之鏈表&動態內存&文件一、定義: 鏈表是一種物理存儲上非連續,通過指針鏈接次序,實現的一種線性存儲結構。二、特點: 鏈表由一系列節點(鏈表中每一個元素稱為節點)組成,節點在運行時動態生成(malloc),每個節點包括兩個部分: 存儲數據元素的數據域 存儲下一個節點地址的

梓益C語言學習筆記常用字符串操作sscanf & strtok

C語言 字符串操作 梓益C語言學習筆記之常用字符串操作(sscanf & strtok)一、sscanf int sscanf(const char *buf,const char *format, …); \\從buf指定的內存區域中讀入信息 例: int a, b, c; ssc

C語言學習筆記字符串拼接的2種方法——strcat、sprintf

fir str return print 文章 %s rst stdlib.h 字符串拼接 本文為原創文章,轉載請標明出處 1. 使用strcat進行字符串拼接 #include <stdio.h> #include <stdlib.h> #incl

C語言學習筆記位運算求余

nbsp 位運算 sdn 縮小 .net 一次 得出 ngs 有效 我們都知道,求一個數被另一個數整除的余數,可以用求余運算符”%“,但是,如果不允許使用求余運算符,又該怎麽辦呢?下面介紹一種方法,是通過位運算來求余,但是註意:該方法只對除數是2的N次方冪

C語言資料結構稀疏矩陣

最近開始學習C語言的稀疏矩陣的一些知識,現在簡單的整理梳理一下知識脈絡,僅供自己總結學習,歡迎技術指正,拒絕盲噴。 1.首先先介紹一下關於稀疏矩陣的一些基礎知識,關於稀疏矩陣,一直都沒有過很清楚詳細的定義。簡單的說,在M*N的一個矩陣中,假設有t個元素不為0,那麼有計算公

C語言學習筆記資料型別

1、整數型別 1.1 型別 型別 位數 short(或short int) 16位 int 16位或32位 long (或long int) 32位 long long(或long lo

C語言開發一個BT下載軟體 ------ 程式碼實現-1-種子檔案解析模組

//parse_metafile.h #ifndef PARSE_METAFILE #define PARSE_METAFILE // 儲存從種子檔案中獲取的tracker的URL typedef struct _Announce_list { char ann

基於C/C++語言資料結構線性表

資料結構學習筆記: 資料結構的重要性:資料結構我感覺很重要,不僅僅是考試很重要,而且在以後程式設計師事業上都是尤為重要的,知乎上有網友評價資料結構是最重要的程式設計基本能力,沒有之一。我感覺這個說法很對,並且大家都知道,資料結構與演算法這種說法常常被大家使用,就是因為資料

Go語言學習筆記-函數部分

個數 pri 用法 err 筆記 註意 語言 pac println 函數部分 函數基本組成:關鍵字func、函數名、參數列表、返回值、函數體、返回語句 例子: func Add(int a, int b) (return int, err error){ ....函數