Objective-C語法簡記


  開始學習iPhone開發了,雖然現在已經有了Swift,但我還是老老實實地學習Objective-C,鄙人入門的程序語言是C,后來學習了C#和Java,現在來學Objective-C,這篇只是一些很簡略的筆記,不算是語法書。

代碼文件

Objective-C的代碼文件有3種,“*.h”的頭文件;”*.m”是普通的源代碼文件,里面可包含Objective-C和C的代碼;“*.mm”也是源文件的一種,里面可包含Objective-C,C和C++的代碼。

最簡單的HelloWorld

1 #import <UIKit/UIKit.h>
2 #import "HGAppDelegate.h"
3 
4 int main(int argc, char *argv[])
5 {
6     printf("Hello world\n");
7     NSLog(@"Hello world");
8 }

取代了以前熟悉的#include預處理命令,換成了#import,但尖括號“<”,“>”還有雙引號的意義與以前一樣,printf語句依然能輸入那句經典的Hello world,在Objective-C中就有了一種新的方式——NSLog(@"Hello world");大凡以NS前綴開頭的類都是系統預先定義好的類,比如字符串NSString,后來的NSArray等。NSLOG傳入了參數也是“Hello world”,但前面多加了一個@,這個是Objective-C字符串的寫法,如果要聲明一個字符串的變量並附初值@”Hello world”,則是

NSString *str=@”Hello world”;

基本數據類型

  Objective-C的基本數據類型和C中的一樣的,int是整形,char是字符,float是單精度浮點數,double是雙精度浮點數,與C有點區別的在於short和long,這兩種在Objective-C寫法是short int和long int,在這里多了一個長雙精度的類型long double。無符號的在前面多加了一個unsigned,寫法如unsigned int。

特有數據類型

  • Id 是指針類型,它的作用與C#/Java的Object類型很類似,可以指向任何引用類型的引用。
  • BOOL 這類型只有兩個值YES和NO,就代表着1和0。在C中這兩個值也代表true和false。
  • SEL 指向函數的指針,定義並附上初值的形式如下
SEL sel=@selector(方法簽名)

SEL sel=NSSelectorFromString(方法名的字符串)

調用的時候則是以下形式

[obj performSelector:sel withObject: nil];

上面obj是對象的實例,sel則是SEL類型的變量,nil則是obj對象的默認值,如果保險起見,調用前要先判斷obj對象有沒有那個方法,則調用下面的方法,它會返回布爾值,ture就是存在,反之則不存在。

[obj respondsToSelector:sel]:

如果要獲取SEL變量所指向的方法的方法名時,可以調用下面的方法,它返回的是一個字符串。

NSStringFromSelector(sel變量):
  • nil,NiL和NSNull nil與C的NULL一樣,是指向空的指針,它算是一個對象,一個什么都沒有的對象;Nil則是代表空的類,是一個Class來的;NSNull出現在集合中,它代表着集合中空的元素。

流程控制語句

  這里講兩種語句switch和foreach,因為這個在C#和Java之間都會有所區別。

  • Switch,switch語句與C中里面的switch一樣,每個case之后可以不需要用break;結束並跳出switch語句,它會順序執行下一個case里面的代碼,直到遇到了break或者到達語句末尾為止。這里的case后面與Java一樣不能跟字符串。
  • Foreach foreach語句與C#的形式很相像,也是foreach(元素類型 item in 集合的變量名)。在循壞體里面與C#不一樣的是它能夠去對被遍歷的集合進行修改,但是由於更改后枚舉器不會做相應的更新,所以如果刪除了某些元素剛好被遍歷到,有可能會出現空引用的異常。

  Objective-C類的定義分聲明與實現兩個操作,感覺和接口的定義與實現很像。

  • 類聲明
@interface ClassName : NSObject
{
    //字段定義
}
    //方法,屬性等其他成員的聲明
@end 
  • 類的實現
@implementation ClassName
    //方法,屬性等其他成員的實現
@end 

方法

方法的聲明語法如下

+(void)methodName(paraType1)paraName1 and:(paraType2)paraName2; 

+代表的是靜態方法,-代表的是實例的方法;后面的括號代表的是返回類型,這里例如上面的方法是空返回void;方法名總在參數的前面,Objective-C的方法名很特殊,按上面聲明的方法,它的方法名師methodName and;參數則是以 :(ParaType)ParaName的形式,如果沒有參數,則方法名后面直接以分號“;”結束。調用則通過以下的形式,objIns則是對象的實例名。

[objIns methodName:value1 and:value2]; 

存取方法

對於私有字段而已要對其獲取或設置都要通過get/set方法來進行,在Java中通過聲明getter/setter方法來實現面向對象編程中的封裝性,在Objective-C中也有這類getter/setter方法,稱之為存取方法。

例如現在有字段int count,他對應的存取方法是

-(void) setCount: (int)couValue;
-(int) count; 

Setter方法則是以set+對應的字段名,setter直接與字段同名。在調用的時候可以用通常方括號的形式”[” ”]”當不普通方法來調用,可以使用類似C#,Java中點”.”的方式調用,如果點的方式調用,則直接跟上字段的名字則可,如

MyClass.count=12;
Int count=myclass.count; 

屬性

如果聲明了一個屬性,則系統會自動為其生成getter/setter方法。這個與C#的屬性挺類似,但是語法形式大不相同。它與類的定義一樣,分別有聲明與實現兩部分

  • 聲明
@property(修飾符) int count;
  • 實現

@synthesize count;

如果在實現的時候要指定這個屬性是對那個字段經行封裝的,可以通過下面的形式,下面則代表了對count字段的封裝,記得指定時有加下划線”_”

@synthesize count=_count; 

在聲明的時候可以指定修飾符,修飾符可以用多個,每個間用逗號隔開,修飾符及其作用如下所示

  • Readwirte:可供讀寫;
  • Readonly:只讀;
  • Strong:強引用,就是我們在C#和Java中通常使用的引用,就是指該對象在沒有被任何一個字段引用才會被GC;
  • Weak:弱引用,就算該對象有被字段引用着,還有可能會被GC;
  • Copy:賦值的時候只給一個副本,不會給它本身;
  • Assign:在通過setter賦值時不會增加該對象的引用計數器,這針對NSString類型和基礎數據類型;
  • Retain:調用時會釋放前一個引用的對象,但是引用計數器會加1;
  • Nonatomic:表明這個屬性不考慮線程安全問題。

如果不使用系統自動生成的getter或setter方法,可以通過在修飾符的地方指定自己定義的getter方法和setter方法的簽名,如

@property(getter=mygetter,setter=mysetter:) int count;

又叫作代碼塊,聲明的語法如下

ReturnType(^BlockName)=^(paraType1 para1,paraType2 para2){ /*代碼內容*/ };

等號左邊相當於聲明塊的變量,等號右邊相當於塊的字面值,塊的效果類似於Lumbda表達式,調用時就如C/C#中調用方法那樣

BlockName(para1,para2);

協議

語法如下

@protocol ProtocoName

//方法聲明

@optional //可選實現

//方法聲明

@required//必須實現

//方法聲明

@end

這個類似於接口,實現是在類的聲明處以下面的形式

@interface ClassName:NSObject<ProtocoName1,…..>

類別

語法如下

@interface ClassName(CategoryName)

    //方法聲明

@end

    //其他代碼

@implementation ClassName(CategoryName)

    //方法聲明

@end 

用於給已經定義的類擴展方法,ClassName是已經定義的類,要被擴展的類,CategoryName是類別名,類別中的方法如果遇到方法簽名一樣的方法,則會覆蓋原有的方法;類別中的成員只局限於方法,字段那些是不能定義的;若是覆蓋了方法,那么那個覆蓋的作用域是整個程序。

Self與supper

  • Self是類隱藏參數,類似Java與C#的this,調用方法時先向本類搜索方法,沒有的話再向父類搜索。
  • Super則是預編譯指令,類似C#與Java的super,但是不完全一樣,這里的super不代表對父類的引用,只是在調用方法時先從父類搜索,如果沒有則再往父類的父類中搜索,只在調用方法時有C#/Java的效果,本質還是對當前類的引用。

內存管理

在開始時調用

NSAutoreleasePool *pool=[ [NSAutoreleasePool alloc] init]; 

結束的時候

[pool release];

構造對象

[[ClassName alloc] init];

釋放對象

[ClassInsName release]; 

規則:1)自己用alloc或者copy創建的對象,在用完的時候要release;2)對不是自己創建的對象,則不要去release;3)retain對象后,要realease,兩者要對稱,有多少個retain就要有多少個release。

異常與錯誤

Objective-C的異常處理與C#和Java差不多,也是由try catch finally語句塊組成,拋異常用throw。格式如下

@try
{  }
@catch(NSException *ex)
{
@throw
}
@finally
{
   
}

和C#的關鍵字一樣的,只是多了個“@”,catch塊中的@thorw只是為了演示用。

在Objective-C中NSError讓人的感覺與NSException類似,都是與錯誤有關,但實際上兩者在用法上大有不同,NSException是異常,記錄異常的信息,異常是在程序出現,會讓程序卡住的。NSError是錯誤,是記錄錯誤的信息,例如調用了某些方法失敗后,會在傳入方法的NSError對象中填寫相關的錯誤信息,有NSError不會讓程序卡死,但出現了NSException不捕捉則會讓程序卡死,NSException可以被拋出和捕捉,NSError沒有拋出和捕捉這個概念。


免責聲明!

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



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