objective-c中非常重要的文法知識,在此歸納總結一下。
類方法,也稱靜态方法,指的是用static關鍵字修飾的方法。此方法屬類本身的方法,不屬于類的某一個執行個體(對象)。類方法中不可直接使用執行個體變量。其調用方式有三種:可直接調用、類名.方法名、對象名.方法名。執行個體方法指的是不用static關鍵字修飾的方法。每個執行個體對象都有自身的執行個體方法,互相獨立,不共享一個。其調用方式隻能是對象名.方法名。
用修飾符static聲明的方法為靜态方法,不用修飾符static聲明的方法為執行個體方法。不管類生成或未生成對象,類的靜态方法都可以被使用,使用格式為:類名.靜态方法名。靜态方法隻能使用該靜态方法所在類的靜态資料成員和靜态方法。這是因為使用靜态方法時,該靜态方法所在類可能還沒有對象,即使有對象,由于用類名.靜态方法名方式調用靜态方法,靜态方法沒有this指針來存放對象的位址,無法判定應通路哪個對象的資料成員。在類建立對象後,執行個體方法才能被使用,使用格式為:對象名.執行個體方法名。執行個體方法可以使用該方法所在類的所有靜态成員和執行個體成員。
何時用靜态方法,何時用執行個體方法?
先說執行個體方法,當你給一個類寫一個方法,如果該方法需要通路某個執行個體的成員變量時,那麼就将該方法定義成執行個體方法。一類的執行個體通常有一些成員變量,其中含有該執行個體的狀态資訊。而該方法需要改變這些狀态。那麼該方法需要聲明成執行個體方法。
靜态方法正好相反,它不需要通路某個執行個體的成員變量,它不需要去改變某個執行個體的狀态。我們把該方法定義成靜态方法。
關于靜态方法和執行個體方法的一些誤區。
一、靜态方法常駐記憶體,執行個體方法不是,是以靜态方法效率高但占記憶體。
事實上,方法都是一樣的,在加載時機和占用記憶體上,靜态方法和執行個體方法是一樣的,在類型第一次被使用時加載。調用的速度基本上沒有差别。
二、靜态方法在堆上配置設定記憶體,執行個體方法在堆棧上。
事實上所有的方法都不可能在堆或者堆棧上配置設定記憶體,方法作為代碼是被加載到特殊的代碼記憶體區域,這個記憶體區域是不可寫的。
三、執行個體方法需要先建立執行個體才可以調用,比較麻煩,靜态方法不用,比較簡單。
事實上如果一個方法與他所在類型的執行個體無關,那麼它就應該是靜态的,決不會有人把它寫成執行個體方法。是以所有的執行個體方法都與執行個體有關,既然與執行個體有關,那麼建立執行個體就是必然的步驟,沒有麻煩簡單一說。實際上上你可以把所有的執行個體方法都寫成靜态的,将執行個體作為參數傳入即可。
有些方法看似與所在的執行個體無關,如IComparer.Compare方法,但實際上每一個實作這個接口的類都隻會負責自己類型執行個體的比較,這是C#1.x規範中沒有泛型所帶來的曆史遺留問題。
大部分靜态方法是與類的執行個體有關的,如各種Parse方法,他做成靜态的原因是他沒有執行個體作為參數。其他的大多是出于語義或者其他目的的考慮。
第一種方式, 聲明執行個體,調用執行個體方法
當一個類有多個執行個體,例如學生這個類,執行個體可以有學生甲,學生乙,學生丙,等等,我們就用第一種方式。在多線程的情況下,隻要每個線程都建立自己的執行個體,那麼第一種方法通常是線程安全的。
第二種方式,通過一個靜态的執行個體,去調用執行個體方法
這種情況比較特殊,通常是整個程式裡該類唯一的一個執行個體,我們通過調用該執行個體的執行個體方法來改變該執行個體的某些狀态。這一個執行個體在多線程的情況下,通常是線程不安全的。除非我們給這個執行個體加鎖。防止其他線程通路該執行個體。
第三種方式,直接調用靜态方法
這種情況下靜态方法不需要去改變某個執行個體的狀态。隻要得到少量的參數就可完成既定事情。比如判斷一個檔案是否存在,隻要給個檔案路徑和檔案名,就能知道該檔案是否存在。
轉載2:
調用一個類的靜态方法需不需要release?(記憶體管理)(面試題)
我個人認為,靜态成員方法不需要對象,不需要release。
注:其實靜态成員方法也是有對象的,叫做類對象,但這個是在第一次通路類成員時觸發系統将其加載到記憶體的,而且該類對象隻在程式立閉時,才會釋放,并不由程式本身控制。
有三個概念要厘清:類、執行個體和對象,類本身加載到記憶體(可能是代碼段的記憶體,不是堆記憶體,也不是棧記憶體),可以叫做一個對象;建立一個類的執行個體,這個執行個體可以叫做一個對象,是以就有類對象和執行個體對象之分了,類對象就是一張圖紙,執行個體對象是按類對象造出的一橦樓,确實都是實實在在存在的東西,是以叫對象,隻不過性質不同,一個是圖紙,一個是按圖紙造出來的樓房。
其實,我也很想知道,這是哪家公司的面試題,搞得這麼不嚴謹。
從這一句話中,可以有兩種了解,一是類的靜态方法中傳回的對象是否需要release;二是調用執行個體方法需要release嗎?就是說要調用release,需要先alloc+init,這時才能調用執行個體對象的方法,使用完了,要release;那麼直接調用類的靜态方法,是否需要release類本身的對象。
從以上分析,能得出這樣的結論:該公司剛接觸objectiv-c;該公司面試的人沒有真正熟練和掌握objective-c,也是剛入門的家夥;最後,可能是面試的人說錯了,或此貼提問的人寫錯了。
轉載3:
這個好文章我要馬克一下,今天碰到“靜态方法”一下子沒反應過來,樓主你可幫了我大忙了,那句“靜态方法不需要release因為沒有對象”也給了我啟發,有時候學多了很容易忘記最基礎的思想。
注:确有同感,早些年,無論是學c++,還是objective-c,又或是java,時間久了,用一些東西成習慣了,就不知道是啥意思了,是以得常反刍,才易消化。
就象學五筆,用五筆,N年之後,好多字不會拆,但常用的能打出來,其實是成了習慣了,而忘了規律。
再比如,你要教小孩子10以内的加減法,看看怎麼教才好,或者你還記得當時怎麼學的嗎?!
20以内的加減法呢?借10法和湊10法,你小時侯學過嗎?俺是沒學過,就是記住,那時沒人教這些個規律,加是正着數,減是倒着數等等,就是賣油翁,手熟爾。00:20:2900:20:30