




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、Learn ObjectiveC原文地址譯者前言在網(wǎng)上看到這篇文章覺得寫的很不錯,但是貌似沒有人翻譯成中文,我就大膽翻譯 了。本人做軟件開發(fā)6年了,但是大多數(shù)是在Windows平臺上,最近才在我的機器上裝 了一個leopard,在ObjectiveC上也是一個新手,對于本文翻譯的是否到位心里還 在打鼓。如果有覺得翻譯不對不好的地方,請與我聯(lián)系,我的油箱是:cchenhao at gmail dot com。cc很好J,謝謝大家。ObjectiveCObjectiveC是開發(fā)Mac軟件的主要編程語言。如果你了解一些面向?qū)ο蟮幕靖拍詈?C語言,那么會對你學(xué)習(xí)ObjectiveC有很多
2、幫助,如果你不了解C,那么建議你先讀一下 C 指南。這篇指南由Scott Stevenson編寫并做圖。方法調(diào)用為了盡快開始,讓我們先看一些例子。調(diào)用一個對象的方法的基本語法是這樣的:object method;object methodWithInput:input;方法可以有返回值:output = object methodWithOutput;output = object methodWithInputAndOutput:input;你還可以調(diào)用類的方法,這也是創(chuàng)建一個對象的辦法。在下面的例子里,我們調(diào)用 了NSSting類的string方法,用來返回一個新的NSString類的對象
3、。id myObject = NSString string;id類型意味著變量myObject可以是任意類型的對象。所以,當你編譯這段代碼時, 它的實際類型以及它所實現(xiàn)的方法編譯器是不知道的。在我們的例子里,很顯然對象的類型是NSString,所以我們可以改變對象的類型 聲明:NSString* myString = NSString string;現(xiàn)在,這就是一個NSString類型的變量了,如果我們在這個對象上調(diào)用NSString類型對象不支持的方法,編譯器就會發(fā)出警告。注意:在對象類型的右面有一個星號(*),在Objective-C中,所有的對象變量 都是指針類型。id類型已經(jīng)被預(yù)定義
4、為指針類型,所以不需要加一個星號。嵌套調(diào)用在許多編程語言中,嵌套的方法或函數(shù)調(diào)用像是這樣的:function1(function2();function2的返回值做為輸入?yún)?shù)傳遞給function1。在Objective-C中,嵌套 調(diào)用看上去像是這樣的:NSString stringWithFormat:prefs format;要盡量避免在一行語句中進行兩層以上的嵌套,這樣會使代碼的可讀性降低。多輸入?yún)?shù)的方法一些方法需要多個輸入?yún)?shù)。在Objective-C中,一個方法的名字可以被拆分成幾段,在頭文件中,多輸入?yún)?shù)的方法聲明看上去像是這樣的:-(BOOL)writeToFile:(NSS
5、tring *)path atomically:(BOOL)useAuxiliaryFile;你可以這樣調(diào)用這個方法:BOOL result = myData writeToFile:”/tmp/log.txt”atomically:NO;這些不是命名參數(shù)。在運行時環(huán)境中,該方法的名字實際上是writeToFile:atomically:訪問器在ObjectiveC中,所有的實例變量默認都是私有的,所以,在大多數(shù)情況下,你應(yīng) 該使用訪問器來獲取或設(shè)置這些變量的值?,F(xiàn)在有兩種語法。下面的是傳統(tǒng)的1.x語法:photo setCation:”Day at the Beach”;output = p
6、hoto caption;第2行代碼不是直接讀取實例變量。實際上它是在調(diào)用名為caption的方法。在Objective-C中,大多數(shù)情況你不用在獲取器(getter)前面添加一個”get”前綴在任何情況下,在方括號中代碼都意味著你是在給一個對象或者一個類型發(fā)送一個 消息(即一個方法調(diào)用)。點操作符在Mac OS X 10.5中,Objective-C 2.0新增了點操作符的設(shè)置器(setter) 和獲取器(getter):photo.caption = ”Day at the Beach”;output = photo.caption;兩種語法你可以使用任何一種,但是在一個項目中最好只使用一
7、種。同時,點語法 只能使用在設(shè)置器(setter)和獲取器(getter)上,而不能用于普通方法。創(chuàng)建對象創(chuàng)建對象有兩種主要的辦法。第一個是之前你看到的:NSString* myString = NSString string;這是一種更加方便自然的方式。通過這種方法,你創(chuàng)建了一個自動釋放 (autoreleased)的對象,這一點我們會在后面看到更多的細節(jié)。盡管如此,在許多 地方,你可能需要通過手工創(chuàng)建的方式來創(chuàng)建一個對象,如下:NSString* myString = NSString alloc init;這是一個嵌套的方法調(diào)用。第一個是NSString類本身的alloc方法調(diào)用。這是一
8、 個相對低層的調(diào)用,它的作用是分配內(nèi)存及實例化一個對象。第二個是調(diào)用新創(chuàng)建對象的init方法。init方法通常做對象的初始化設(shè)置工作, 比如創(chuàng)建實例變量。作為一個類的使用者,你無法知道這些方法的實現(xiàn)細節(jié)。在某些情況下,你可以使用init方法的另外一種版本,這些版本帶有輸入?yún)?shù):NSNumber* value = NSNumber alloc initWithFloat:1.0;內(nèi)存管理基礎(chǔ)當你為Mac OS X編寫應(yīng)用程序時,你可以選擇允許垃圾回收。這意味著如果不是 在特別復(fù)雜的情況下,你不用考慮內(nèi)存管理。然而,你并不會總是工作在支持垃圾回收的環(huán)境中。這樣的話,你就需要知道一些 基本概念。如果
9、你通過手工alloc的方式創(chuàng)建一個對象,之后你需要release這個對象。同樣, 你也不能手工釋放(release)一個能自動釋放(autoreleased)的對象,因為這將會 使你的應(yīng)用程序崩潰。以下是兩個例子:/string1 將被自動釋放NSString* string1 = NSString string;/必須在用完后手工釋放NSString* string2 = NSString alloc init; string2 release;在這里,你可以認為自動釋放對象會在當前函數(shù)結(jié)束的時候被自動釋放。 關(guān)于內(nèi)存管理要學(xué)的東西很多,但是我們先了解一下其他的概念,這樣我們會有更多的認識。
10、設(shè)計類接口在Objective-C的語法中,創(chuàng)建一個類是非常簡單的。一個類通常分為兩部分。類的接口(interface)通常存放在類似ClassName.h的文件中,在這里,我們定義實例變量和公用(public)方法。類的實現(xiàn)存放在ClassName.m這樣的文件中,它包含了這些方法的實際實現(xiàn)代碼。 它通常還定義了客戶類不能訪問的私有(private)方法。一個接口文件看上去像以下這樣的。這個類名字叫做Photo,所以接口文件名是Photo.h:#import <Cocoa/Cocoa.h>interface Photo : NSObject NSString* caption;N
11、SString* photographer;end首先,我們導(dǎo)入了Cocoa.h,目的是將Cocoa應(yīng)用程序的基本類添加進來。#import指令會自動防止將同一個文件導(dǎo)入多次。interface表明這是類Photo的聲明。冒號后面指定父類(superclass),這里 父類是NSObject。在花括號里面聲明了兩個實例變量:caption和photographer。都是NSString類型,實例變量可以是任何對象類型,包括id類型。最后,end符號結(jié)束類的聲明。添加方法讓我們給實力變量添加一些獲取器(getter)#import <Cocoa/Cocoa.h>interface P
12、hoto : NSObject NSString* caption; NSString* photographer;- caption;- photographer;end記住,Objective-C語言中通常省略方法的“get”前綴。方法名字前面的單個減 號(-)表明該方法是一個實例方法。如果方法名字前面是一個加號(+),則表明該方法 是一個類(static)方法。編譯器會默認一個方法的返回值是一個id類型的對象,所有的輸入?yún)?shù)也默認是id 類型。上述代碼在技術(shù)上是正確的,但是我們一般不這樣寫,我們需要給這些方法指定 返回值類型。#import <Cocoa/Cocoa.h>in
13、terface Photo : NSObject NSString* caption; NSString* photographer;- (NSString*)caption;- (NSString*)photographer;end現(xiàn)在,我們來添加設(shè)置器(setter):#import <Cocoa/Cocoa.h>interface Photo : NSObject NSString* caption; NSString* photographer;- (NSString*)caption;- (NSString*)photographer;- (void) setCaptio
14、n: (NSString*)input;- (void) setPhotographer: (NSString*)input;end設(shè)置器不需要有返回值,所以我們指定返回值是void。類實現(xiàn)現(xiàn)在,我們從獲取器(getter)開始,來創(chuàng)建一個類的實現(xiàn)。#import "Photo.h"implementation Photo- (NSString*) caption return caption;- (NSString*) photographer return photographer;end這段代碼以implementation和類的名字開始,并且像接口一樣,有一個end
15、。 所有的方法必須寫在這兩條語句之間。如果你寫過代碼,就會覺得上面的獲取器看上去很熟悉,所以我們還是來看一看設(shè) 置器,它們需要多一點解釋。- (void) setCaption: (NSString*)inputcaption autorelease;caption = input retain;- (void) setPhotographer: (NSString*)inputphotographer autorelease;photographer = input retain;每一個設(shè)置器都要處理兩個變量,第一個是當前引用的對象,第二個是新輸入的對象。在帶有垃圾回收機制的環(huán)境中,我們可以
16、直接設(shè)置成新的值。- (void) setCaption: (NSString*)inputcaption = input;但是,如果你不能使用垃圾回收,你需要release舊的對象,并且retain新的對 象。釋放一個對象的引用實際上有兩種方法:release 和 autorelease。標準的 release會立刻釋放對象的引用。autorelease會等一會兒才釋放,但是引用實際上 會一直存在,直到當前方法結(jié)束(除非你添加自定義的代碼來明確的改變它)。在設(shè)置器里面使用autorelease方法會更加安全一些,因為要改變的變量的新舊兩 個值可能指向的是同一個對象。而你可能不希望立刻釋放實際
17、上你要保留的對象?,F(xiàn)在,這看上去有點讓人迷惑,但是隨著你的不斷學(xué)習(xí),你就會有更多的認識。所 以,現(xiàn)在不必徹底的理解這些。Init我們可以創(chuàng)建一個init方法用來給我們的實例變量設(shè)置初始化值:- (id) initif ( self = super init )self setCaption:"Default Caption"self setPhotographer:"Default Photographer"return self;這段代碼是完全不需要加以說明的,盡管第二行看上去有點不常見。它是一個單個 的等號(=),作用是將super init的結(jié)果賦
18、值給self。這實際上是要求父類做(父類的)初始化操作。if語句的作用是在嘗試設(shè)置(本對 象的)缺省值之前驗證父類是否初始化成功。Deallocdealloc方法在一個對象從內(nèi)存中刪除時被調(diào)用。通常在這個方法里面釋放所有對象 里的實例變量。 (void) dealloccaption release; photographer release; super dealloc;在前兩行,我們直接調(diào)用了實例變量的release方法。在這里,我們不需要使用autorelease,因為標準的release更快一些。最后一行非常重要,我們發(fā)送了一個super dealloc消息,要求父類做清理工作。如果我
19、們不做的話,該對象就不會被從內(nèi)存中刪除,這就造成了內(nèi)存泄露。當啟用垃圾回收機制時,對象的dealloc方法不會被調(diào)用。此時,你可以實現(xiàn)一個finalize方法來代替它。內(nèi)存管理Objective-C的內(nèi)存管理是基于引用計數(shù)的。你要做的事情只是關(guān)注你的引用,而釋放內(nèi)存的工作實際上由運行環(huán)境完成。在最簡單的情形中,你分配的(alloc)對象,或者是保留(retain)在一些地方 的對象,都需要給他們發(fā)送一個release消息。這也意味著,如果你使用了一次alloc, 然后又retain了一次,那么你需要release兩次才能釋放該對象的內(nèi)存。這就是引用計數(shù)的理論。在實際應(yīng)用中,通常只有兩個原因我們
20、才會創(chuàng)建一個對象:1作為一個實例變量保留。2在函數(shù)內(nèi)部作為臨時變量使用。大多數(shù)情況下,一個實例變量的設(shè)置器(setter)會自動釋放(autorelease)原來引用的對象,同時保留(retain)新的。你只需要保證在dealloc函數(shù)中釋放(release)了它就行了。那么,我們實際要做的工作就只有管理函數(shù)內(nèi)部的本地引用了。在這里只有一條規(guī)則:如果過你通過alloc或者copy創(chuàng)建了一個對象,在函數(shù)結(jié)尾的地方給它發(fā)送一個release或者autorelease消息就行了。如果你是通過其它方式創(chuàng)建的對象,就什么 也別做。下面是第一個例子,管理實例變量:- (void) setTotalAmou
21、nt: (NSNumber*)inputtotalAmount autorelease;totalAmount = input retain;- (void) dealloctotalAmount release; super dealloc;下面是另外一個例子,關(guān)于本地引用。我們只需要釋放通過alloc創(chuàng)建的對象就行了:NSNumber* value1 = NSNumber alloc initWithFloat:8.75; NSNumber* value2 = NSNumber numberWithFloat:14.78;/ only release value1, not value2
22、value1 release;下面是一個組合例子,將一個本地引用設(shè)置給實例變量:NSNumber* value1 = NSNumber alloc initWithFloat:8.75; self setTotal:value1;NSNumber* value2 = NSNumber numberWithFloat:14.78; self setTotal:value2;value1 release;注意,不論你是不是把本地引用當成實例變量一樣賦值,管理它們都是完全相同的。 你不必考慮設(shè)置器(setter)是如何實現(xiàn)的。如果你理解了這些,你就理解了關(guān)于Objective-C內(nèi)存管理中90%你需
23、要知道的內(nèi)容。日志記錄在Objective-C中,將日志信息輸出到控制臺是非常簡單的。實際上NSLog()函數(shù)很像C語言里面的printf()函數(shù),除了要用一個%符號代表一個對象。NSLog ( "The current date and time is: %", NSDate date );你可以將一個對象的信息作為日志在控制臺輸出。NSLog函數(shù)調(diào)用該對象的 description方法,并且將這個方法返回的NSString打印到控制臺。你可以在你的 類中重寫這個方法以返回你自定義的字符串。屬性(Properties)前面我們寫了caption和author的訪問方法,你
24、可能也注意到了,那些代碼很簡單,應(yīng)該可以寫成具有更普遍意義的形式。屬性是Objective-C的一個特性,它允許我們自動生成訪問器,同時還有其它方面 的好處。我們用屬性來改寫一下Photo類。之前的代碼看上去是這樣的:#import <Cocoa/Cocoa.h>interface Photo : NSObject NSString* caption; NSString* photographer;- (NSString*) caption;- (NSString*) photographer;- (void) setCaption: (NSString*)input;- (voi
25、d) setPhotographer: (NSString*)input;end用屬性改寫后的代碼看上去是這樣的:#import <Cocoa/Cocoa.h>interface Photo : NSObject NSString* caption; NSString* photographer;property (retain) NSString* caption;property (retain) NSString* photographer;endproperty是Objective-C語言的一個指令,通過它聲明屬性。帶括號 的”retain”指示設(shè)置器(setter)要保留
26、輸入值,該行后面的是指定屬性的類型以 及名稱。下面我們看看這個類的實現(xiàn)部分:#import "Photo.h"implementation Photosynthesize caption;synthesize photographer;- (void) dealloccaption release; photographer release; super dealloc;endsynthesize指令為我們主動生成了setter和getter,所以我們必須要做的就 只有實現(xiàn)dealloc方法了。只有當訪問器不存在的時候,synthesize才會自動生成訪問器,所以,即使是使
27、 用synthesize聲明了一個屬性,你仍然可以實現(xiàn)自定義的getter和setter。編譯 器只會自動生成你沒有自定義的方法。關(guān)于屬性的聲明還有很多選項,但是它們超出了本指南的范圍。在Nil上調(diào)用方法在Objective-C中,nil對象的作用等同于很多其他語言的NULL指針。不同的地方在于,在nil上調(diào)用方法不會導(dǎo)致程序崩潰或拋出異常。這種技術(shù)被用在很多地方,但是對于我們來講,最主要的就是我們不用在調(diào)用一個對象的方法之前檢查該對象是否為空。如果你調(diào)用了一個nil對象的方法并且該方法有 返回值的話,你會得到一個nil返回值。我們也可以用它來稍微改進一下我們的dealloc方法:- (voi
28、d) deallocself.caption = nil; self.photographer = nil; super dealloc;可以這樣做是因為當我們將nil賦值給一個實例變量,設(shè)置器(setter)會釋放舊對 象并且保留(retain)nil對象。這種做法對于dealloc來說更好一些,因為這樣做 避免了讓變量指向一個隨機的數(shù)據(jù),而這個數(shù)據(jù)又恰好是另外一個對象。注意,我們在這里使用了self.<var>語法,這表示我們使用的是setter,它會進 行內(nèi)存管理。如果我們僅僅是直接設(shè)置值,像下面這樣,那就會產(chǎn)生內(nèi)存泄露:/ incorrect. causes a memory leak./ use self.caption to go through setter caption = nil;類目(Category)類目是Objective-C中最有用的一個特性。實質(zhì)上,類目允許你為一個已存在的類添加一些方法而不用子類化該類,也不需要你了解該類的實現(xiàn)細節(jié)。這是特別有用的,因為你可以給一個內(nèi)建的對象添加方法。當你想在
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度解除影視制作解除擔保合同
- 二零二五年度個人債權(quán)轉(zhuǎn)讓及債務(wù)清收執(zhí)行合作協(xié)議
- 二零二五年度跨境離婚協(xié)議書電子化執(zhí)行合同
- 二零二五年度子女自愿離婚協(xié)議書范本及離婚后子女監(jiān)護權(quán)
- 二零二五年度認繳制智能硬件股權(quán)轉(zhuǎn)讓合同
- 2025年度林業(yè)碳匯項目承包樹木砍伐協(xié)議
- 二零二五年度酒店客房租賃及旅游套餐協(xié)議
- 二零二五年度智能停車場年產(chǎn)權(quán)車位轉(zhuǎn)讓服務(wù)協(xié)議
- 2025年度車輛抵押貸款欠款和解與債務(wù)重組服務(wù)合同
- 二零二五年度房地產(chǎn)項目房地產(chǎn)投資顧問合作協(xié)議
- 金融服務(wù)消費糾紛調(diào)解工作規(guī)范
- 《國際貿(mào)易實務(wù)(英文版)》(英文課件) - Ch 1 Introduction to International Trade Practices-Ch 5 Price
- 新生兒科、兒科《新生兒窒息復(fù)蘇》理論考試試題
- 神經(jīng)重癥氣管切開患者氣道功能康復(fù)與管理專家共識(2024)解讀
- 2024年企業(yè)管理咨詢服務(wù)費簡單合同范本
- 4.城軌工程項目勞務(wù)分包指導(dǎo)價(車站.盾構(gòu).鋪軌)4
- 2024年安全生產(chǎn)網(wǎng)絡(luò)知識競賽題庫及答案(共五套)
- 輸變電工程施工質(zhì)量驗收統(tǒng)一表式(線路工程)
- 普通工安全技術(shù)操作規(guī)程交底注意事項(8篇)
- 2025屆江蘇省十三大市高三沖刺模擬歷史試卷含解析
- 《高等數(shù)學(xué)(第2版)》 高職 全套教學(xué)課件
評論
0/150
提交評論