從C#到Objective-C电湘,循序漸進學(xué)習(xí)蘋果開發(fā)(2)--Objective-C和C#的差異

本隨筆系列主要介紹從一個Windows平臺從事C#開發(fā)到Mac平臺開發(fā)蘋果開發(fā)的一系列感想和體驗歷程梅屉,本系列文章是在起步階段逐步積累的,希望帶給大家更好彪薛,更真實的轉(zhuǎn)換歷程體驗茂装。
在上篇《從C#到Objective-C怠蹂,循序漸進學(xué)習(xí)蘋果開發(fā)(1)--準備開發(fā)賬號和開發(fā)環(huán)境》介紹了一些基本的轉(zhuǎn)換感悟和一些基礎(chǔ)的準備工作,還沒有正式真實的介紹Objective-C和C#的之前差異少态,我們知道城侧,從一種環(huán)境或者一種語言轉(zhuǎn)換過去另外一種,我們都會做一些對比和理解彼妻,這樣可以很容易把我們頭腦的知識進行對接嫌佑,在這個所有東西日益大同的背景下,我們相信侨歉,所有的語言特點都是相通的屋摇。

1、面向?qū)ο蟮念?/h3>

1)類的定義
Objective-C(下稱OC)和C#都是面向?qū)ο蟮恼Z言幽邓,雖然OC比C#古老炮温,起源自C,但是很多特點和C#都很接近了牵舵,在C#3.0里面才引入的擴展方法柒啤,在OC里面也存在了。
OC和C#都一樣畸颅,他們繼承的關(guān)系都是單繼承的白修,沒有C++的那種多重繼承那么復(fù)雜,OC很有特點的一個要求就是把接口和實現(xiàn)完全分開重斑,這點是熟悉C#開發(fā)的人員必須轉(zhuǎn)換過來的思路兵睛,在OC里面,寫一個類窥浪,先寫接口定義祖很,然后再寫實現(xiàn),它的語法和C#很大不同漾脂,但是也很容易理解假颇。
OC的關(guān)鍵字一般都是以@符號進行標(biāo)識,這點和C#的默認保留關(guān)鍵字不同骨稿,一般看到@interface, @property, @關(guān)鍵字笨鸡,在最新版本的XCode里面,真是發(fā)揮到了極致了坦冠,包含了很多語法糖形耗,基本上和C#走向了大同,這點在對象的初始化繼續(xù)介紹辙浑。
OC的類定義放到.h文件里面激涤,實現(xiàn)放到了.m文件里面,如下面是類的接口聲明判呕。

@interface SimpleClass : NSObject
 
@end

而類的實現(xiàn)操作如下所示倦踢。

#import "SimpleClass.h"
 
@implementation SimpleClass
 
@end

上面只是一個演示類的概念送滞,一般情況下,類都有屬性或者方法辱挥,因此還需要增加很多東西犁嗅。

另外OC和C#對比,沒有了命名空間的概念晤碘,OC的類為了避免混淆一般通過前綴進行區(qū)分褂微,如你看到的IOS基礎(chǔ)類庫,很多帶有NS哼蛆,UI蕊梧,CA霞赫,等這樣的前綴腮介,就是這個原因。

2)方法的定義

如下面的接口聲明一個方法端衰,方法的定義

@interface XYZPerson : NSObject
- (void)sayHello;
@end

我們看到叠洗,上面的方法定義(接口定義)很簡單,這里有一個 - 符號旅东,是用來標(biāo)識屬于實例方法的灭抑,還有一種屬于類級別的方法,用+符號標(biāo)識抵代,這個加號腾节,類似于C#語言里面的static關(guān)鍵字,默認在方法定義為-的實例方法荤牍,都是類似于C#里面的public方法了案腺。
這個(void)定義是返回值的標(biāo)識,C#是不需要括號的void標(biāo)識無返回值康吵,方法最后需要括號標(biāo)識劈榨。

  • (void)sayHello;
    這個方法的定義沒有參數(shù)因此是這樣寫的,如果方法有多個參數(shù),這個OC就很有意思晦嵌,我感覺這個是OC里面最有個性的一個地方了同辣。
    如果方法如下所示:
  • (void) setCaption: (NSString*)input;
    類方法的調(diào)用是通過空格,而C#通過點進行調(diào)用惭载,這點也有所不同旱函,OC通過在一個[]里面空格進行引用,如下所示描滔。
[object method];
[object methodWithInput:input];

剛才定義的sayHello方法陡舅,它的調(diào)用可能就是如下方式了

[self setCaption:@"Default Caption"];

如果方法的定義為多個參數(shù)(也叫多重參數(shù)),定義如下伴挚。

-(void) setNumerator: (int) n andDenominator: (int) d; 

那么方法的調(diào)用就很有意思了靶衍。

[frac2 setNumerator: 1 andDenominator: 5]; 

如果還有更多的參數(shù)灾炭,那么也就一直使用這樣的累加方式,這個有點接近閱讀習(xí)慣颅眶,呵呵蜈出。
3)參數(shù)的定義
說完方法的定義和使用,我們介紹下類里面的屬性的定義涛酗,我們知道C#里面的屬性定義很簡單了铡原,如

public string Name {get;set;}

回來看看OC如何定義屬性的,一般在.h的接口定義里商叹,可以這樣定義燕刻。

@property NSString *firstName;
@property NSString *lastName;

然后在實現(xiàn)類代碼里面,添加它的對應(yīng)代碼@synthesize的關(guān)鍵字

@synthesize firstName, lastName;

屬性當(dāng)然也可以指定為只讀的剖笙,如下代碼所示

@property (readonly) NSString *fullName;

另外卵洗,我們還需要清楚,屬性默認是線程安全的弥咪,也就是atomic过蹂,還有它是強類型Strong的。

@interface XYZObject : NSObject
@property NSObject *implicitAtomicObject;          // atomic by default
@property (atomic) NSObject *explicitAtomicObject; // explicitly marked atomic
@end

在很多地方聚至,我們使用屬性的時候酷勺,都不需要指定它的線程安全特性,因為那樣效率更高扳躬,一般的屬性定義代碼如下所示脆诉。

@property (strong, nonatomic) IBOutlet UILabel *lblName;
@property (strong, nonatomic) IBOutlet UITextField *txtInput;

至于是不是所有的屬性都應(yīng)該指定為Strong,這個肯定不是的贷币,strong的另外一種類型是weak击胜,它是表示弱類型,強類型和弱類型主要是針對ARC來說的片择,它是引用計數(shù)的范疇潜的,Strong相當(dāng)于原來的retain。
一般情況下字管,為了避免一些強類型的對象屬性導(dǎo)致出現(xiàn)相互引用的問題啰挪,在代理類和數(shù)據(jù)源對象,還有一些如UITable的對象屬性嘲叔,他們的屬性定義必須指定為weak的亡呵。

2、對象的類型和初始化工作

在C#里面硫戈,我們知道锰什,它里面包含了有一些基本類型(Primitive type)和一些包裝后的對象類型,如它的基本類型包括string int char float long double decimal等等,它的對應(yīng)包裝類型有String Int32 Char Single Int64 Double Decimal等等汁胆。
在OC里面梭姓,同樣也有這樣的情況,OC的基本類型繼承自C語言的基礎(chǔ)類型嫩码,包括有int float double char 等基礎(chǔ)類型誉尖,也有很多NS開頭的引用類型(或者說包裝類型),如NSString NSNumber NSDate NSData NSValue等等铸题,而很多集合類型NSArray NSMutableArray NSDictionary等都需要添加引用類型的對象铡恕。
另外和C#的Object對象類似或者動態(tài)類型關(guān)鍵字dynamic指定的類型一樣,OC里面包含了一個id的類型丢间,這個是一個不確定的類型探熔,它可以看成是一個任何類型的弱定義乓梨。
id類型是一個獨特的數(shù)據(jù)類型如叼,在概念上,類似java的Object類丛肮,可以轉(zhuǎn)換為任何數(shù)據(jù)類型墙牌。換句話說涡驮,id類型變量可以存放任何數(shù)據(jù)類型的對象暗甥。在內(nèi)部處理上喜滨,這種類型被定義為指向?qū)ο蟮闹羔槪瑢嶋H上是一個指向這種對象的實例變量的指針撤防。需要注意的是id是一個指針虽风,所以在使用id的時候不需要加星號;比如說:id foo=nil;
1)類對象的初始化
我們知道寄月,OC里面很多都是通過alloc init這樣的方式進行初始化辜膝,如下面代碼所示。

XYZObject *object = [[XYZObject alloc] init];

而C#里面大多數(shù)使用new方式進行初始化漾肮,其實OC里面厂抖,也一樣可以通過new方式進行初始化,不過僅限在默認構(gòu)造函數(shù)的方式進行克懊,如下的代碼是等同于上面的語句的忱辅。

XYZObject *object = [XYZObject new];

不過好像很多人都習(xí)慣用第一種方式初始化對象。
2)字符串的初始化
相信很多人使用OC的時候谭溉,第一個印象最深的我覺得可能是NSString類了墙懂,這個是和C#的String有點類似,都是固定的字符串對象扮念,如果需要變化類型的字符串對象损搬,C#里面是可以使用StringBuilder,而OC里面可以使用NSMutalbeString,NSMutableString好比一個字符串鏈表巧勤,它可以任意的動態(tài)在字符串中添加字符串 刪除字符串 指定位置插入字符串嵌灰,使用它來操作字符串會更加靈活。
字符串的定義和初始化和簡單颅悉,我們可以通過下面的方式進行初始化伞鲫。

NSString *someString = @"Hello, World!";

我們知道,C#也可以使用@字符進行賦值签舞,雖然一般情況使用在多行的情況下秕脓,但是在OC,這個@字符不能省略儒搭。
其他數(shù)據(jù)類型初始化吠架,很多都依靠@字符進行,這個@字符可以說是非常強大的搂鲫,它也可以說是一個很好的語法糖傍药,如下面初始化各種類型的代碼如下(在OC里面,NSNumber可以放置任何引用類型)

    NSNumber *myBOOL = @YES;
    NSNumber *myFloat = @3.14f;
    NSNumber *myInt = @42;
    NSNumber *myLong = @42L;

NSNumber類型可以裝納各種類型魂仍,同樣它也可以轉(zhuǎn)換為其他對應(yīng)的類型拐辽,如下代碼所示

   int scalarMagic = [magicNumber intValue];
    unsigned int scalarUnsigned = [unsignedNumber unsignedIntValue];
    long scalarLong = [longNumber longValue];
 
    BOOL scalarBool = [boolNumber boolValue];
 
    float scalarSimpleFloat = [simpleFloat floatValue];
    double scalarBetterDouble = [betterDouble doubleValue];
 
    char scalarChar = [someChar charValue];

另外,由于OC里面引入了一個id類型擦酌,可以認為它的作用和C# 3.0引入的動態(tài)類型相當(dāng)俱诸,它可以在運行時進行確定對象是否具有某個方法,而不會在編譯的時候強制指定赊舶。

如下面的代碼編譯通過睁搭,運行的時候可能出錯。

id someObject = @"Hello, World!";
[someObject removeAllObjects];

之所以編譯的時候笼平,不檢查它的對象是否有removeAllObject接口方法园骆,是因為這兒的someObjec指定為了id的動態(tài)類型,所以編譯器會不檢查它的方法寓调。

3)對象集合的初始化

剛才上面介紹了字符串等各種類型的初始化锌唾,很多采用了強大的關(guān)鍵字@進行初始化,這個語法糖減少了很多繁瑣的方法調(diào)用夺英,對于集合的初始化晌涕,尤其這樣。

如果按照傳統(tǒng)的集合定義方式秋麸,一般是通過下面的方法渐排。

NSArray *someArray =
  [NSArray arrayWithObjects:someObject, someString, someNumber, someValue, nil];

在里面的集合,最后必須加上一個nil的東西灸蟆,這個在C#的領(lǐng)域里面是不需要增加這樣的標(biāo)識的驯耻,在Object C里面亲族,如果你要通過arrayWithObjects方法進行構(gòu)造,必須增加一個這樣的東西可缚,告訴它這個是最后了霎迫,如果你把這個放到第二位,那么構(gòu)造的集合也只有兩個對象了帘靡,很奇怪了知给。
如果采用了強大的@方法構(gòu)造,一切都和C#相似了描姚,這里你只能佩服它的神奇之處了涩赢。

NSArray *someArray = @[firstObject, secondObject, thirdObject];

如下面定義一個字符串的集合是這樣的。

NSArray *unsortedStrings = @[@"gammaString", @"alphaString", @"betaString"];

在C#里面轩勘,我們經(jīng)常用到了字典對象筒扒,這個對象非常方便。當(dāng)然在OC里面绊寻,也肯定會有這樣的東西花墩,畢竟很多語言都會支持的。
這個字典類型也是一個集合類型澄步,它的傳統(tǒng)構(gòu)造方法如下所示

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
             someObject, @"anObject",
             @"Hello, World!", @"helloString",
             @42, @"magicNumber",
              someValue, @"aValue",
              nil];

它這個看起來很怪異冰蘑,添加指點是按照object,key的這樣方式添加的,這個與我們使用C#的習(xí)慣有很大的不同哦村缸,而且最后還帶了一個nil的尾巴祠肥。

如果采用@構(gòu)造函數(shù),一切又都清凈了王凑,已經(jīng)是key,value方式進行存儲搪柑,而且不用nil了聋丝,如果你添加了nil索烹,那么會出錯的。

NSDictionary *dictionary = @{
   @"anObject" : someObject,
   @"helloString" : @"Hello, World!",
   @"magicNumber" : @42,
   @"aValue" : someValue
};

集合中弱睦,如果取某個對象百姓,那么通過下面的方法進行獲取

NSNumber *storedNumber = [dictionary objectForKey:@"magicNumber"];

也可以通過下標(biāo)括符進行獲取

NSNumber *storedNumber = dictionary[@"magicNumber"];

如果是一般的數(shù)組集合,可以通過下面方式獲取况木,這種方式和c#很類似了垒拢。

NSNumber *storedNumber = array[0];

由于時間和篇幅的問題,關(guān)于OC的各種和C#對比的特性火惊,以后繼續(xù)介紹求类,OC里面還涉及很多相關(guān)的特點,如擴展方法屹耐,協(xié)議(類似接口)尸疆,代碼塊等等內(nèi)容,以及XCode的各種使用特性,有空繼續(xù)介紹寿弱。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末犯眠,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子症革,更是在濱河造成了極大的恐慌筐咧,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件噪矛,死亡現(xiàn)場離奇詭異量蕊,居然都是意外死亡,警方通過查閱死者的電腦和手機艇挨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進店門危融,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人雷袋,你說我怎么就攤上這事吉殃。” “怎么了楷怒?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵蛋勺,是天一觀的道長。 經(jīng)常有香客問我鸠删,道長抱完,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任刃泡,我火速辦了婚禮巧娱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘烘贴。我一直安慰自己禁添,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布桨踪。 她就那樣靜靜地躺著老翘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锻离。 梳的紋絲不亂的頭發(fā)上铺峭,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天,我揣著相機與錄音汽纠,去河邊找鬼卫键。 笑死,一個胖子當(dāng)著我的面吹牛虱朵,可吹牛的內(nèi)容都是我干的莉炉。 我是一名探鬼主播啤呼,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼呢袱!你這毒婦竟也來了官扣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤羞福,失蹤者是張志新(化名)和其女友劉穎惕蹄,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體治专,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡卖陵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了张峰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泪蔫。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖喘批,靈堂內(nèi)的尸體忽然破棺而出撩荣,到底是詐尸還是另有隱情,我是刑警寧澤饶深,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布餐曹,位于F島的核電站,受9級特大地震影響敌厘,放射性物質(zhì)發(fā)生泄漏台猴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一俱两、第九天 我趴在偏房一處隱蔽的房頂上張望饱狂。 院中可真熱鬧,春花似錦宪彩、人聲如沸休讳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽衍腥。三九已至,卻和暖如春纳猫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背竹捉。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工芜辕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人块差。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓侵续,卻偏偏與公主長得像倔丈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子状蜗,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,747評論 2 361

推薦閱讀更多精彩內(nèi)容