objective-c 語法快速過(1)

有必定 c++或者 java 基礎,過一遍 oc 語法便可,都是相通的,我的認爲難點是 oc 的內存管理,雖然有了 ARC,可是也須要學習下,由於有舊軟件的維護。java

創建在C語言的基礎上,增長了一層小範圍的面向對象的語法(保留了面向對象最精華的部分,oc的內容沒有java多,而java的內容沒有c++多,c++的內容最爲繁雜),OC徹底兼容C語言,c和oc能夠混編。能夠在OC代碼中混入C語言代碼(前提是oc源文件擴展名是.m),甚至是C++代碼(不是全部的源文件都能包含c++代碼,只有源文件擴展名是.mm的源文件能夠包含c++代碼)。c++

可使用OC開發Mac OS X平臺和iOS平臺的應用程序objective-c

關鍵字編程

基本上全部關鍵字都是以@開頭,一些常見的關鍵字框架

@interface、@implementation、@end、@public、@protected、@private、@selector、@try、@catch、@throw、@finally 、@protocol、@optional、@required、@class、@property、@synthesize、@dynamic、self、super、id、_cmd、__block、__strong、__weak函數

字符串以@開頭學習

好比@"Hello"是OC中的字符串,而"Hello"則是C語言中的字符串,其中,@和字符串必須緊挨着。ui

註釋spa

註釋的語法和C 同樣。設計

nil

OC 中的 nil 至關於 c 和 c++的NULL 

OC程序的開發過程

編輯,編譯,連接(把全部的相互關聯的.o文件合併在一塊兒,加上函數庫),運行。

和c相似,先編寫.m文件(文件名能夠是中文),而後編譯器編譯,連接,運行。

 

NSLog與printf的區別

一、NSLog接收OC字符串做爲參數,printf接收C語言字符串做爲參數

二、NSLog輸出後會自動換行,printf輸出後不會自動換行

三、使用NSLog須要#import <Foundation/Foundation.h>,裏面有NSLog函數的聲明。不須要刻意記憶,想不起來,就編譯,出錯就會提示缺乏什麼。

四、能夠只包含框架的主頭文件,效果等價包含了這個框架裏的全部的頭文件。頭文件在Xcode裏面,路徑很深,很差找。使用printf須要#include <stdio.h>

#import的做用(預處理)

一、跟#include同樣,用來拷貝某個文件的內容

二、能夠自動防止文件內容被拷貝屢次,也就是頭文件中不用和C同樣,加入下面的預處理指令了

#ifndef  xxx xxx

#define xxx xxx

#endif

Foundation框架的做用

開發iOS、Mac程序必備的框架,此框架中包含了不少經常使用的API。框架中包含了不少頭文件,若想使用整個框架的內容,包含它的主頭文件便可

#import <Foundation/Foundation.h>

至關於#include 導入頭文件 也有兩種查找方式< ... > 和" ... "。

當包含一個頭文件,編譯時,須要找到那個頭文件,使用< >這種方式,編譯器查找的時候,會在編譯器的安裝目錄的標準庫中開始查找," "這種方式,會在當前的工程所在的文件夾開始尋找,也就是源程序所在的文件夾。有的編譯器,要求十分嚴格,不能混用,有的就能夠。

BOOL的使用(徹底能夠當作整型用)

BOOL類型的本質:

typedef signed char BOOL;

BOOL類型的變量只有兩種取值:YES、NO

#define YES (BOOL)1

#define NO  (BOOL)0

BOOL的輸出(當作整數來用);

NSLog(@"%d %d", YES, NO);//1 0

C裏沒有布爾類型,c++,java裏有,oc也有。不過oc的布爾和c++有區別,在C++裏一切非 0 值的東西都爲 true,而爲0值的爲false。可是Object-c裏必須是1爲 true ,且並被宏定義爲 YES,0 爲 false 並被宏定義爲 NO。

因此下面的代碼,則確定是得不到想要的運行順序。

複製代碼
 1 #import <Foundation/Foundation.h>
 2 BOOL isBool(int, int);
 3 
 4 int main(void)
 5 {
 6     if (isBool(5, 1) == YES) {
 7         NSLog(@"ok");
 8     }
 9     return 0;
10 }
11 BOOL isBool(int x, int y)
12 {
13     return x - y;
14 }
複製代碼

4不是1,在oc裏永遠都不會等於YES(由於 oc 中的YES就是1),注意:BOOL大寫,YES 和 NO 也是大寫,OC 裏的YES就是1,NO就是0

多個.m文件的開發和混合開發

跟C語言中多文件的開發是同樣的,回憶c多文件開發,常量的定義或者函數的聲明寫在xxx.h文件,函數的定義寫在xxx.c文件,主文件main.c裏寫主程序和函數調用,最後#include xxx.h文件,一塊兒編譯主文件main.c和xxx.c文件便可。

面向對象經常使用術語

  • 面向過程 Procedure Oriented
  • 面向對象 Object Oriented,簡稱OO
  • 面向對象編程 Object Oriented Programming,簡稱OOP

OC中的面相對象

1)       類至關於圖紙,用來描述一類事物。

2)       利用類來建立對象,對象是類的具體存在

3)       所以,面向對象解決問題應該是先考慮須要設計哪些類,再利用類建立多少個對象 

定義OC的類和建立OC的對象

定義一個新類分爲 2 部分:

@interface 部分;

描述類、類的數據成分以及類的方法

@implementation 部分;

實現這些方法的實際代碼

 

@interface 部分的通常格式:

@interface NewClassName : ParentClassName

{

memberDeclarations;

}

methoddeclarations;

@end 

@implementation 部分的通常格式:

@implementation NewClassName

methodDefinitions;
@end //NewClassName 表示的名稱與@interface 部分的類名相同

要描述類分2大步驟:類的聲明、類的實現(定義)。

跟函數相似,函數也分聲明和定義。而聲明一個類又須要三大要素:類名,屬性,行爲,相似 c++。

命名規則:

以字母或下劃線開頭,以後能夠是任何字母,下劃線或者0~9 數字組合。

約定:

類名以大寫字母開頭,命名有意義、好比駝峯標識。

實例變量、對象以及方法的名稱以小寫字母開始。每次建立新對象時,將同時建立一組新的實例變量且惟一。

注意:在對象類型的右邊都有一個 *號,全部的對象變量都是指針類型。

id (萬能指針)類型已經被預約義爲指針類型,因此不須要加一個*號。 

  • 類的聲明,關鍵字@interface後一個空格,跟一個類名,而後最後必須寫@end,告訴編譯器類聲明完畢
  • 類的聲明用來聲明對象的屬性(成員變量,也叫實例變量)和行爲(方法)
  • : NSObject 繼承一個類(在Foundation框架裏)
  • 花括號裏用來寫對象屬性,不能寫方法
  • 方法(行爲);寫在花括號外,@end 前
    三要素:方法名,參數,返回值(相似函數,分聲明和實現),方法的聲明在類的聲明裏,且不能寫在花括號裏。
    方法雖然相似c的函數,可是和函數千差萬別
    只要方法是對象的方法,則聲明前必須加一個減號-,這是規則!
    oc方法裏的任何數據類型都必須用小括號()括起來
    oc方法的小括號就一個做用,就是括住數據類型的。故- (void) run();是不對的!
  • 類的實現,相似於類的聲明語法,也要寫@end
  • 對象裏的成員變量,能夠取值整型的,那麼默認初始化爲0
  • oc方法的實現,必須寫在類的實現裏,說清楚方法裏有什麼。

方法開頭的(-)號或者(+)號表示:
(-) 該方法是實例方法(對類的特定實例執行一些操做) ;

(+)是類方法(即對類自己執行某些操做的方法,例如建立類的新實例) 

oc 通常的方法的聲明示例:

-(void)setNumerator :(int)n

第一個表示方法類型(對象方法-),返回類型(空void),接着是方法名(包括冒號:),方法接受的參數類型int和參數名n

注:若是不帶參數則不用使用「:」號

若是沒有指定任何返回類型, 那麼默認是id類型, 全部的輸入參數默認也是id類型 (id類型可用來引用任何類型的對象,屬於萬能指針類型) 。

 oc 裏具備多個參數的方法聲明示例:

-/+ (return type) function_name : (parameter type) parameter1 otherParameter : (parameter_type) parameter2;

若是隻有一個參數,在: 後面聲明參數的類型和名稱

若是有多個參數的話,每一個參數前面都要有一 個 :,接着是參數類型和參數名稱。

在 objective c 中,對於有多個參數的函數,能夠理解爲將函數的名稱拆 成了幾個部分,每一個部分都是對緊接着的參數的一個解釋 ,很是方便,作到見名知意,oc 官方文檔也是,尤爲帶多個參數的方法名字每每特別的長。

如在 C++中多個參數的方法聲明:

void initializeRectangle(int x1, int y1, int x2, int y2); 

但並不知道這些參數都是什麼意思,但在objective-c 中,能夠這樣聲明:

void initializeRectange: (int)x1 LeftUpY :(int)y1 RightBottomX: (int)x2 RightBottomY:(int)y2; 

利用類建立對象

oc裏,想執行一些行爲,必須寫上一個中括號[],方括號左面是類的名稱或者該類實例的名稱,空格後面是方法(即消息) 

[classOrInstance method];
執行Car這個類的new行爲來建立對象,分配了內存,每一個對象都有本身的存儲空間來存儲本身的成員變量等元素
youCar = [Car new];//建立了一個Car類的對象,返回對象的地址(返回對象)。以後內存裏存在這個對象了。
oc裏想操做對象,只能用指針去間接操做!
Car *p = [Car new];//把地址保存到指針裏,p指向的是Car類型的對象
給p指向的對象的屬性賦值
 p->speed = 200;

內存分析(對象在內存中有成員)

[Car new]每次都會建立出新的對象,而且返回對象的地址,那麼就應該用一個指針變量保存對象的地址

Car *c = [Car new];//用一個指針變量c指向內存中的Car對象     

設置車子對象的屬性,跟用指向結構體的指針訪問結構體屬性同樣,用->

c->wheels = 3;

c->speed = 300;

對象在內存裏的變化和狀態圖

oc 類成員的訪問屬性:

oc類屬性,默認是@protected,本類內部和繼承的類能訪問,而外部沒法訪問,須要手動設置爲public。

@pubic

有一個典型的錯誤

oc千萬不能想固然的和c++,java混淆,不用在類實現裏再添加花括號了,直接寫方法的實現便可。

 和c++的不一樣,oc的類佔據一分內存空間

在第一次使用類的時候,類被加載到內存裏,即在建立對象以前,先給類分配內存空間。

一、存放類的內存只被加載一次(第一次使用對象的時候,加載對象屬於的類)便可,且裏面只存放方法的列表。

二、內存裏每一個類的對象的存儲空間內部,默認都有一個指針叫isa指針,每一個對象都有,做用是:指向這個對象所對應的類(存放類的內存塊,幫助找到對象所屬的類),因此全部的對象都共用一份方法,因此類只被加載一次便可。成員變量每一個對象都有本身的那一分內存,可是方法就共用一分內存

三、調用方法的過程:

[person1 walk]; 

執行:

給指針person1指向的對象發送一條walk消息,去調用那個對象的walk方法,而後對象會順着isa指針找到對應的類,去類裏找方法,找到walk方法,就前往對應的代碼去執行,就在walk方法裏訪問當前對象的成員變量age和weight(由於成員變量,每一個對象都有本身的一份

再次強調:將對象賦給id類型變量不會有問題。

注:不管在哪裏,對象老是攜帶它的isa的保護成員(一個指針,能夠用來肯定對象所屬的類) ,因此即便將它存儲在id類型的通用對象變量中,也老是能夠肯定它的類 。

面向對象封裝的好處

  • 更加接近人類的思考方式
  • 只須要關注對象,不須要關注步驟 
  • 可是注意:oc的對象不會自動去回收,一旦建立,一直存在內存裏,除非手動釋放,或者程序執行完畢。因此,函數建立的對象不會消失。可是沒有指向它的指針存在了。
  • 注意,oc 裏,方法和函數是有本質的區別的,不要混淆!
相關文章
相關標籤/搜索