【Objective-C 篇】 ☞ 1. 基礎、語法


1. 第一個OC程序

框架(Framework)

CHello不同:

1) 擴展名(后綴名).m

2) 使用Foundation框架

3) 使用#import導入頭文件:

#import <Foundation/Foundation.h>

#import 會自動處理頭文件重復導入問題

4) 使用NSLog函數輸出日志信息

5) 使用clang編譯器,並且連接Foundation框架:

clang -framework Foundation xxxx.m (編譯時要注意指定Foundation框架)

 

Unix/Linux/蘋果系統下可執行文件的后綴名可以是任何文件,可以是任意后綴名或沒有后綴。

如,a.out==a.txt (都可以執行!)

總結一個文件擴展名(后綴名):

.c ===C語言源程序文件

.m ===OC

.cpp ===C++

.cc ===》某些Unix系統的C++

.mm ===Objective C++

 

.s ===》匯編

.i ===》經過預處理后的源程序

.o ===》編譯還沒連接的二進制文件

.o.out cc++Objective-C語言編譯后生成的文件)

 

.a ===》靜態庫文件

.so ===Unix/Linux下的動態庫文件

.dylib ===Mac OS/iOS 動態庫文件

2. 編譯器

C語言標准編譯器是: gcc   OC早期的編譯器使用gcc  gcc不是蘋果公司的)

OC現在的編譯器:

clang (蘋果公司自己開發的,獨立的編譯器)

LLVM(小的一個語言虛擬機)集成在Xcode中【特點:隨時編譯,方便Xcode自動隨時檢查語法錯誤】

C語言編譯器:gcc

OC語言的編譯器:clang (由於OC語言兼容所有的C語言語法,所以也可以用clang編譯器編譯C程序)

3. Xcode寫OC程序

  

  只需要在C語言字符串前面加上@符號, 系統就會自動將C語言字符串轉換為OC字符串。

4. 面向對象編程

4.0 定義

面向對象編程: 直接使用解決現實生活中問題的辦法來解決計算機問題。

4.1 對象

Anything is Object 萬物皆對象,現實中,對象是一種客觀上的存在。

程序中對象是一片內存空間,這片空間中存放表示對象的數據。

對象:類這種類型的變量

對象中有:

有什么      屬性

能干什么   方法

 

4.1.1 系統中的對象:

一個對象有可能由若干個小對象組成

對象職能單一,一個對象只做自己該做的事

對象們各司其職,各盡所能

對象與對象之間有一定聯系,之間用發消息的方式進行工作

這些對象構建成一個運行的系統。

 

4.1.2 %@打印一個對象(實例對象/類對象):

只要利用%@打印某個對象, 系統內部默認就會調用父類的description方法

打印對象的本質是:打印description方法中的字符串!

    

4.1.3 匿名對象

有名字的對象:只要用一個指針保存了某個對象的地址, 我們就可以稱這個指針為某個對象(稱p為TRPerson的對象)

TRPerson *p = [TRPerson new];

p.name = @"張三";

p.age = 22;

[p show];

沒有名字的對象

無論有沒有名字, 只要調用new方法都會返回對象的地址

每次new都會新開辟一塊存儲空間

[TRPerson new].name = @"張三";

[TRPerson new].age = 22;

[[TRPerson new] show];

4.2

類是類型的意思,現實中是一種主觀的認識

在計算機中,類是自定義類型,是創建對象的模型(模板)

類就是用於描述對象的共性特征,主要用於描述對象的屬性和行為

類中有:屬性的定義和方法的定義

4.2.1 類的本質:類其實也是一個對象(類對象),這個對象會在這個類第一次被使用的時候創建。

  • 只要有了類對象, 將來就可以通過類對象來創建實例對象
  • 實例對象中有一個isa指針, 指向創建自己的類對象
  • 類對象中保存了當前對象所有的對象方法
  • 當給一個實例對象發送消息的時候,會根據實例對象中的isa指針去對應的類對象中查找

類對象代表類,class類型,對象方法屬於類對象

如果消息的接收者是類名,則類名代表類對象

所有類的實例都由類對象生成,類對象會把實例的isa的值修改成自己的地址,每個實例的isa都指向該實例的類對象。

 

4.2.2 如何獲取類對象?

Class c = [類名/實例對象 class];

 

類對象的應用場景:

  • 用於創建實例對象

TRPerson *p3 = [c1 new];

TRPerson *p4 = [[c3 alloc]init];

  • 用於調用類方法

[c3 method];//等價於[TRPerson method];

 

4.2.3 類的啟動過程(系統內部自動調用的兩個方法:load方法 initialize方法)

  • load方法:程序一啟動就會調用
    • 只要程序啟動就會將所有類的代碼加載到內存中, 放到代碼區
    • load方法會在當前類被加載到內存的時候調用, 有且僅會調用一次
    • 如果存在繼承關系, 會先調用父類的load方法, 再調用子類的load方法
  • initialize方法:
    • 當類第一次被使用的時候就會調用(創建類對象的時候)
    • initialize方法在整個程序的運行過程中只會被調用一次, 無論你使用多少次這個類都只會調用一次
    • initialize用於對某一個類進行一次性的初始化
    • initializeload一樣, 如果存在繼承關系, 會先調用父類的initialize再調用子類的initialize

   

4.3 OC中定義類和創建對象

4.3.1 定義一個類

分兩部分:接口部分,實現部分

1、接口部分

聲明類的目的: 告訴系統我們這個類中有哪些屬性和方法

@interface  類名 : 父類名   //類開始

//定義屬性

//聲明方法(相當於聲明函數)

@end   //類結束

2. 實現部分

@implementation 類名

//方法的定義(相當於定義函數)

@end

 

4.3.2 創建對象

創建對象使用alloc,創建好后用一個指針將對象的地址保存起來,以便后面使用。我們把保存對象地址的指針叫引用(Reference)

類名 *引用名 = [類名 alloc];

通過類創建對象

1) 開辟存儲空間,通過alloc(new)方法創建對象會在堆內存中開辟一塊存儲空間

2) 初始化所有屬性

3) 返回指針地址

創建對象的時候返回的地址其實就是類的第0個屬性的地址

但是需要注意的是: 類的第0個屬性並不是我們編寫的第一個屬性,而是一個叫做isa的屬性isa是一個指針, 8個字節

isa屬性是系統內部自動幫我們添加的,當你創建一個對象的時候,系統自動生成isa屬性

isa是一個指針,占8個字節

isa的作用:會指向創建這個類的那個類

     

其實類也是一個對象,也就意味着MyClass也是一個對象(類對象)

     平時我們所說的創建對象其實就是通過一個 類對象 來創建一個 新的實例對象

     類對象是系統自動幫我們創建的,里面保存了當前對象的所有方法

     而實例對象是程序自己手動通過alloc(new)來創建的,而實例對象中有一個isa指針就指向了創建它的那個類對象

 

4.3.2 對象的存儲細節

類創建對象,每個對象在內存中都占據一定的存儲空間,每個對象都有一份屬於自己的單獨的成員變量,所有的對象共用類的成員方法。

方法在整個內存中只有一份,類本身在內存中占據一份存儲空間。

OC中對象創建

TRPerson *p = [TRPerson new];// 等價於 TRPerson *p = [[TRPerson alloc]init];

怎么理解這句話:

理解1:定義了一個TRPerson類型的指針變量,指針變量指向新申請的內存空間

理解2:用TRPerson類實例化了(創建了)一個實例對象,對象的名稱是p

這里的new做了三件事:

  1. 向計算機申請內存空間
  2. 給類中的每一個成員賦初值
  3. 返回新申請的空間的首地址

    

  

    

4.4 定義屬性

1) 在接口部分定義屬性:

@property int x;

@property double y;

@property NSString *name; //對象只能通過引用訪問,所以要加*(指針類型)

//NSStringOC中的字符串類型,*name代表一個指針,OC語言中字符串類型是一個對象,只能用一個指針來保存一個對象的地址,而不能直接保存一個對象;所有的對象都一樣,不能直接用變量來保存對象,只能用一個指針來保存對象的地址!MyClass *obj = [MyClass alloc];

@property NSString *name;//姓名

@property int age;//年齡

@property BOOL gender;//性別

@property double salary;//工資

 

2) 訪問對象中的屬性:

引用.屬性 = 值;

NSLog(@"%d", 引用.屬性);

// %@打印字符串對象

NSLog(@“姓名: %@,性別: %@“, self.name,self.gender?@"":@"");

 

4.5 聲明和定義方法

1) 在接口部分聲明方法

- (返回值類型)方法名;   

- (返回值類型)方法名:參數表;

2) 在實現部分定義方法

- (返回值類型)方法名 {

//寫具體的實現代碼 

}

//OC中方法名會被分解成若干個部分分散在多個參數的前面。

//此方法的方法名是:"setName: age: gender: salary:"

- (void)setName:(NSString *)name

            age:(int)age

          gender:(BOOL)gender

          salary:(double)salary;

3) 調用

通過對象來調用方法

[引用 消息]; //向引用指向的對象發消息(消息的名字應該是方法名),如果引用指向的對象有和這個消息名字相同的方法,就會自動調用此方法。如果沒有這個方法,程序崩潰。

4.6 實際開發中類的寫法

實際開發中,類的接口部分和實現部分是分開的,接口部分放在頭文件中,實現部分放在.m文件中

類名加前綴,防止命名沖突(蘋果官方的前綴是兩個字母,為了不與官方的重復,開發者一般用3個字母的前綴)

5. 方法(Method)

5.1 概念

本質是函數,在OC中寫法和函數不同。

在方法中可以訪問屬性。

當一個對象收到一個消息時,調用對應的方法。

5.2 分類:

實例方法(instance method): -

類方法(class method): +

.h中聲明的所有方法作用域都是public類型,不能更改。

5.3 實例方法(instance method)

實例(instance)指的是對象。一個類的對象可以被稱為這個類的一個實例。

必須通過對象來調用的方法叫實例方法。具體的來說是通過指向對象的引用來調用。

5.4 實例方法的參數

無參、一個參數、多個參數

5.5 方法的返回值

和函數一樣

輸出一個對象詳細信息的兩種方法:

     

5.6 函數和方法的區別

1) 函數屬於整個文件, 方法屬於某一個類,方法如果離開類就不行

2) 函數可以直接調用, 方法必須用對象或者類來調用

3) 不能把函數當做方法來調用, 也不能把方法當做函數來調用

 

6. 成員變量、實例變量(instance variable)

6.1 概念

實例就是對象

每個對象(實例)都有一份自己獨特的數據和別的對象不同,這些獨特的數據會保存在對象的一些特殊變量中,這些變量就是實例變量。

每一個實例都有一份獨特的實例變量。實例變量用來記錄和保存數據!

 

有人也叫成員變量

C++  member variable  成員變量

member function  成員函數

6.2 定義成員變量(在OC里也叫實例變量)

//在大括號中聲明的變量都為成員變量

{

    UIButton *_button;

    int age;

    id data;

}

 

成員變量的常用作用域有3種:

  1. @public 全局都可以訪問
  2. @protected 只能在類內部和子類中訪問
  3. @private 只能在類內部訪問

 

6.3 實例變量和屬性的關系

屬性的本質:兩方法(settergetter+ 實例變量

當我們在類中定義一個屬性時,編譯器會生成以下內容:

1) 保存屬性值的實例變量,名字為"_屬性名"

2) 修改實例變量值的setter方法,名字為"set屬性名",並且屬性名的首字母大寫

3) 讀取實例變量值的getter方法,名字為"屬性名"

比如,定義的屬性名叫name,生成的實例變量名為"_name",生成的setter方法的名字為:"setName:",生成的getter方法的名字為:"name"

 

怎么訪問實例變量?

在實例方法內(類內部),可以直接訪問實例變量。(如:_age=22;

在實例方法外(類外部),用以下兩種方式訪問:

    1)用->直接進行訪問;

如:f->_name = @“張三”;  f->_age = 20; 一般不用!

如果使用,要用@public公開實例變量(實例變量默認是受保護的:@protect),才能用->訪問

    2)用方法間接訪問(setter/getter),屬性是訪問實例變量的一種方式。

setter方法可以給實例變量賦值,getter方法可以獲取實例變量的值。)

 

6.4 實際開發中的經驗:

一般情況下,很少會定義實例變量,而會大量的定義屬性。

在頭文件中,盡量不要定義實例變量,而是定義屬性。

 

OC中的實例變量相當於java中的成員變量,OC中經常用實例變量來存數據。

 

有時候我們會在.m文件中定義實例變量,保存一些私有的數據。也就是說在implementation中定義。

.h文件中的是公開的,.m文件是私有的:

.h文件中定義的屬性(實例變量)是公開的,在.m文件中定義的屬性(實例變量)是私有的。

.h文件中聲明和在.m文件中實現的方法是公開的,只在.m文件中實現,未在.h文件聲明的方法是私有的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM