Objective-C中一些 值得程序員注意的地方:
1.有關於BOOL陷井方面有如下方面:
關於BOOL條件語句中的比較最好是與NO的值來進行比較,因為BOOL的YES與NO值只是約定,並且編譯器將BOOL認作8位二進制數據。若是不小心將一個長於1字節的整型值賦值給BOOL變量,那么只有底位字節將會用做BOOL的值,假設底位字節剛好為0的話,那么BOOL的值將會是0,即NO值,所以關於比較方面推薦用變量值與NO值進行比較。
2.Objective-C中一些基礎的語法問題:(重要聲明:Objective-C就是C,不是什么其他的語言)
NS****命名規則:簡單來說就是以NS為前綴加上匈牙利命名法。
#import在 Objective-C中的使用情況:#import在 Objective-C程序中相當於#include在C/C++中的用法,但是前者在功能上面與后者是有一定的區別,簡單說一點:前者可保證頭文件只被包含一次,而不管此命令在那個文件中實際出現(使用)了多少次。在c語言中,程序員通常使用機遇#ifdef命令的方案來避免一個文件包含另一個文件,而后者又包含第一個文件的情況,在objective-c中,程序員使用#import實現這個功能。
NSLog()和@"字符串"在objective-c中的使用情況:
NSLog()函數在Objective-C中的作用相當於Console、printf()在c/c++語言中的作用。NSLog()還有時間戳、日期戳和自動添加換行符('\n')等一些Console與printf()不具備的功能。在Objective-C中@符號是其在標准c語言基礎上添加的特性之一,""雙引號中的字符串前有一個@符號,這表示引用的字符串應該作為Cocoa的NSString元素來處理。
NSString的部分功能有:
a.告知其長度;b.將自身與其他字符串進行比較;c.將自身轉換為整型值或者浮點值。
在Objective-C中多參數方法的簡要介紹:
多參數方法需要抓住的一點是后面的參數都需要寫上名字。
在 Objective-C中加號、減號、中括號他們的意義與用法:
首先需要了解的一點是在 Objective-C中是沒有public與private的概念的,即可以認為全部都是public。減號表示的是一個函數、方法、消息的開始。加號則表示不需要創建一個類的實例,其他類就可以直接調用這個類中的函數(也可以說加號表示靜態的成員函數)。中括號在 Objective-C中表示方法的調用(通常在 Objective-C中都是說"消息")。下面一段轉換關系就可以清楚的搞懂中括號的使用了:[[[MyCalss alloc] init:[foo bar]] autorelease]; 其轉換為C#或者Java的語法如:MyCalss.alloc().init(foo.bar()).autorelease(); 這段轉換關系非常的重要。
最后關於部分重要東西及個別問題的介紹:
1.id:
Objective-C有一種比較特殊的數據類型是id,可以理解為"隨便"。等價於c語言中的void *;在Objective-C里一切數據都是以指針的形式保存,你獲取到的就是這個對象在內存的位置,而id就是你知道的這個位置。
2.同一個數組可以保存不同的對象:
在Objective-C中數組(NSArray)里面可以保存各種不同的對象,通過以下例子來表示:{myArray<—|0:(float)234.33f 1:@"要玩娛樂" 2:(NSImage *) (圖片資源) 3:@"世紀大光棍"}以上這個數組包含了4個元素,分別是浮點數、字符串以及圖片。
3.BOOL、YES、NO:
在Objective-C中通常把YES等價於C#、Java、C、C++中的true,把NO等價於false,而實際上YES為1,NO為0,BOOL本身是一個char型數據(編譯器認作為8位二進制數據)。
4.IBOutlet、IBAction是什么東西,為什么總能看見:
在語法中IBOutlet、IBAction沒有太大作用,若是希望在Interface Builder中能看到這個控件對象,那么在定義的時候前面加上(IBOutlet),在IB里面就能看到這個對象outlet,如果希望在Interface Builder里控制某個對象執行某些動作,就在方法前面加上(IBAction).實際上IBOutlet、IBAction就跟void是一樣的。
5.nil的意義是什么:
在Objective-C里NULL(空)就是用nil來表示,nil表示空指針。
6.@"字符串"與"字符串"有什么不同或者區別:
"字符串"是C的字符串,@"字符串"是把C的字符串轉換成NSString的一個簡寫.在需要NSString的地方才需要這個轉化,例如:NSLog里面.在需要C string的地方,還是用"字符串"的形式.另外,@""這個轉換是不支持中文的,例如NSLog(@"字符串");是一定輸出不了中文的.
3.函數原型和聲明方式:
首先:先行下短線—即是“減號”,每種方法的名稱、方法的返回值的類型和某些參數。先行短線后面接着就是返回值.
中綴符:Objective-C中有一種名為中綴符(infix natation)的語法技術,方法的名稱及其參數都是合在一起的.如:可以這樣調用帶一個參數的方法:[circle setFillColor:kRedColor];帶兩個參數的方法調用如下:[textThing setStringValue:@"hello there"color: kBlueColor];setStringValue:和color:實際上是參數的名稱(實際上是方法名稱的一部分,后面在詳細介紹),@"hello there"和BlueColor是被傳遞的參數.
冒號:有參數的方法時通常是方法的名稱結尾處是冒號,冒號之后緊接着就是這個參數類型及其參數名.冒號之后的圓括弧中是參數的類型.在無參數的方法中在方法的名稱結尾處通常是不需要添加冒號的而是分號.這里是非常需要注意的,有時候就是因為在沒參數的方法后面加上了冒號而導致程序出現了錯誤信息是沒有意義的初級錯誤.
總結出以下情況為函數原型及聲明的一般形式: - (方法的類型) 方法的名稱: (參數的類型) 參數的名稱; 或者是: - (方法的類型) 方法的名稱;
最后:聲明完成后必須在最后一句加上@end來告訴編譯器類的聲明已經完成.這也是很重要的一處基礎.
4.實現代碼的指令及需要注意的地方:
編譯器同過@implementation這個指令來為某個類提供代碼,類名出現在@implementation之后,該行的結尾處沒有分號,因為在Objective-C編譯器指令后不必使用分號.在@implementation指令中各個方法的定義,不必按照在@interface指令中的順序出現,甚至可以在@implementation中定義那些在@interface中沒有相應聲明的方法。可以把他們(這里的他們是指的是:在@interface中沒有相應聲明的方法)看成私有的方法,僅在類的實現中使用。在這里有一點需要注意:在Objective-C中是不存在真正的私有方法.也就是說單獨在@implementation指令中定義的方法是能從外部進行訪問的,這算是Objective-C動態本質的副作用.傳遞隱藏的參數是另一種間接操作的事例.Objective-C運行時(runtime)可以將不同的對象當成隱藏的self參數傳遞,所以哪些對象的實例變量發生更改時,運行時也可以進行相應的更改.
說明:用戶運行應用程序時,Objective-C運行時是支持這下應用程序(包括我們自己的應用程序)的代碼塊,運行時執行非常重要的任務,如向對象發送消息和傳遞參數.
5.實例化對象:
Shapes-Object中最后的、非常關鍵過程,在該過程中,我們創建形狀對象,例如紅色的圓形和綠色的矩形,這個過程的專業術語就叫做實例化(instantiation).實例化對象時,需要分配內存,然后這些內存被初始化並保存一些有用的默認值,這些值不同於你在 獲得新分配的內存時得到的隨機值,內存分配和初始化完成后,就闖將了一個新的對象實例.這里有一點需要注意:由於對象的局部變量特定於該對象的實例,因此我們稱它們為實例變量,通常簡寫為ivars.
為了創建新對象,我們需要向相應的類發送new消息,因此接收並處理完new消息后,我們就會得到一個可以使用的新對象實例.
Objective-C有一個極好的特性,你可以把類當成對象來向類發送消息,這種便捷的行為不局限於某個特定的對象,而是對全體類都通用,這種消息通常用在創建新對象時,如果需要創建新的circle對象,請求Circle類創建新對象比請求某個現有的circle對象更合適一些.
第4章節:
1.繼承:~~@interface Circle: NSObject~~冒號后的標識是需要繼承的類,因為可以從非類中繼承對象.Cocoa,NSObject繼承對象,因為NSObject提供了大量有用的特性(當繼承一個已繼承自NSOvhect的類時,你也能獲取這些特性).Objective-C中繼承不支持多繼承,想在Objective-C中獲得多繼承的優點,那么就要使用Objective-C的其他特性,如:分類和協議,在本書12、13章有介紹.
2.重構:移動和簡化代碼的方式稱為重構,這在OOP社區中是一個非常時尚的話題.進行重構時,你通過移動某些代碼來改進程序的架構,正如我們在這里把程序中重復代碼刪除,而不改變代碼的行為或運行結果一樣,通常的開發周期包括想代碼中添加某些特性,然后通過重構刪除所有的重復的代碼.通常,在面向對象的程序中添加某些新特性后,程序反而變得更簡單,你可能對此覺得很奇怪,這就想我們添加了Shapes類后所出現的情況.
說明:因為繼承在子類和超類只見建立了一種"is a"(是一個)關系,所以NSObjec的實例變量稱為isa.即Rectangle是一種Shape,Circle是一種Shape,使用Shape的代碼也可以使用Rectangle或Circle來代替.使用更具體種類的對象(Rectangle或Circle)代替一般類型(Shape),這種能力稱為多態性(polymorphism),它在希臘語中形象地表示"很多形狀".
小心易碎:編譯器使用"基地址加偏移"機制實現奇妙的功能.給定的對象基地址,是指第一個實例變量的首個字節在內存中的位置.通過在該地址加上偏移地址,編譯器就可以查找其他實例變量的位置.如:如果圓角矩形對象的基地址是0x1000,則isa實例變量的地址是0x1000+0,即位於0x1000位置,isa的值占4個字節,因此,下一個實例變量fillColor的起始地址位於4個偏移地址之后,即位於0x1000+4位置,或寫作0x1004,,每個實例變量與對象的基地址都有一個偏移位置.如果訪問方法中的fillColor實例變量,編譯器生成代碼並得到存儲self的位置值,然后加上偏移值(在本例中為4),得到指向存儲變量值的位置.隨着時間的推移,這也回產生一些問題,現在,在編譯器生成的程序中,這些偏移位置是通過硬編碼實現的.盡管蘋果公司的工程師希望向NSObject中添加其他的實例變量,但他們無法做到,因為這樣做會改變所有實例變量的偏移位置.這被稱為脆弱的基類問題(fragile base class problem).通過在Leopard中引入新的64位Objective-C運行(它使用間接尋址方式確定變量的位置),蘋果公司解決了這個問題.
3.重寫方法:有時候為了在類中引入某個獨特的特性,需要添加新方法.還有時候可能需要替換或增強由這個新類的某個超類所定義的現有方法.(使某方法為空,當方法中的子類都各自實現了自己的功能方法時,就說方法實現了重寫).涉及關鍵字有:super(超類)。
說明一點:重寫方法時,調用超類方法總是一個不錯的選擇,這樣可以實現更多的功能.通過用調用super來實現機會,這樣可以 保證能夠獲得方法的所有特性。
第5章節:
1.什么是復合:將多個組建組合在一起配合使用,從而得到完整的作品.這里需要注意的一點是:從嚴格上來講,只有對象間的組合才能叫做復合,諸如int,float,enum和struct等基本類型都被認為是對象的一部分.
提醒:如果類中沒有包含人和實例變量,就可以省去代碼中的花括號。
需要記住的有:通過NSLog()可以使用%@格式說明符來輸出對象.NSLog()處理%@說明符時,它會詢問參數列表中相應的對象以得到這個對象的描述.從技術上說,就是NSLog()給這個對象發送描述消息,然后對象的description方法生成一個NSString並返回.之后NSLog()在其輸出中包含這個字符串.在類中添加description方法就可以自定義NSLog()如何輸出對象.
2.存取方法:存取方法(accessor method)是用來讀取或改變對象特定屬性的方法。類存取方法稱為setter方法。另外一種存取方法就getter方法。getter方法為使用對象的代碼提供了讀取對象屬性的途徑。
3.修改方法(mutator)是用來改變對象狀態的方法。需要說明的一點:在其對象的屬性進行操作時,應該始終使用對象所提供的存取方法,永遠不要直接改變其對象屬性的數值。存取方法是程序間接工作的另一個例子。
4.防御式編程:在存取方法中使用通用代碼來檢查實例變量的數組索引,以保證它是有效數值,若是超出了有效范圍,那么程序就會輸出錯誤信息並且退出,那么該段代碼就是所謂的防御式編程.(編程者需要考慮種種可能出現的問題,並且設置異常拋出機制,引申到編程者換位思考的問題上,就可發現出程序所欠缺的部分待優化的功能)。
注意:繼承的適用范圍,切記不要用復雜的系統來繼承包含在本系統中的模塊,如:簡單來說父與子的血脈繼承關系是單向的,所以繼承也需要考慮適用范圍問題。
第7章節-深入了解Xcode:
1.使用編輯器的技巧與訣竅:
Xcode會在開發者鍵入代碼法過程中給出建議,這是Xcode的代碼提示功能,通常叫做代碼自動完成功能.
Xcode中的快捷鍵:command鍵加上“[”、“]”兩個鍵的功能是把當前光標位置的一行代碼進行整體左移跟整體右移。command鍵加上“/”則為把當前光標位置的一行代碼進行行注釋。
2.括號匹配:輸入程序代碼時,也許在輸入了某些字符(如")"、"]"或"}")后屏幕會有些閃爍,這就是Xcode在告訴在這里與之對應的開括號在哪里.這就是Xcode的"括號匹配",也可以雙擊某個分隔符,Xcode會選定它以及與它匹配的括號之間的全部代碼.
3.批量編輯:選擇File->Make Snapshot(快捷鍵command-control-S),Xcode會記住項目的當前的狀態.先在你就可以隨心所欲的"破壞"你的項目.如果意識到犯了一個很嚴重的錯誤,那么可以通過File->Snapshots來恢復你的快照.在這里若是要做什么項目上的重大的修改的時候都推薦備份一份代碼跟保留一份修改當前一個完整版本的代碼快照.(說明:備份代碼的重要性,因為在實際上快照被存儲在一個磁盤鏡像中,它存放於~/Library/Application Support/Developer/Shared/SnapshotRepository.sparseimage.有時候這個磁盤鏡像可能會被損壞(也許因為生活壓力太大了),這時Xcode會向你報告一個“神秘”的錯誤:Snapshot Failed:A project snapshot cannot be created.如果開發者看到了這樣的錯誤,請嘗試刪除這個景象並重新啟動).
4.Xcode中的查找與替換功能:此功能在子菜單Edit->Find中.里面有幾個非常方便的選項.Find in Project可以在項目的所有文件里進行查找和替換.其實這種查找與替換工作並不是很好使用,如:若是開發者只是想重命名函數中的變量,那么它做了過多的操作(因為它可能會改變整個文件中的變量名稱),而開發者想重命名一個類時,它又無法辦到,另外重要的一點,它不能重命名源文件.<在這里又有兩個功能可以彌補這些不足:1.可以簡稱為Edit all in scope,開發者可以選定一個符號,如局部變量或參數,然后選擇Edit->Edit all in Scope,然后在開發者輸入時,所有該符號出現的地方都會立即更新,這不但是進行大量改動的快捷方式,而且操作是看起來很"酷",輸入完畢之后,只要在源文件編輯窗口單擊其他地方,就會離開Edit all in Scope模式。2.“內置重構工具”,若開發者有一個GUI程序,它甚至能夠深入到nib文件的層次進行修改操作,在需要修改的文件中設置插入點,然后選擇Refactor,為了保險需要確保Snapshot復選框被選中,單擊Preview之后,Xcode會分析出要做什么,並將結果展示出來.可惜的是,重構並不能重命名注釋中的文字,所以類末注釋、Xcode生成的頭文件注釋或者任何開發者編寫的文檔注釋都需要手工編輯,開發者可以使用查找和替換功能來簡化這一過程.
5.代碼導航:這里參考博客園中的emacs快捷鍵。http://blog.sina.com.cn/s/blog_6aafe9c90100u4mj.html這篇文章很重要.
7.任意搜索:Xcode項目窗口的右上角右一個搜索框,Xcode通過開發者輸入的字符來過濾瀏覽器中顯示的內容.要使用這個索搜框,首先要在Groups&Files列表中選定任意項,如Source文件夾,然后瀏覽器會顯示該文件夾里的所有源文件。在搜索框中輸入文本可以對這些文件進行篩選。
8.芝麻開門:假如開發者正在看某個源文件,看到了文件上方的#import,如果能夠徐素打開這個頭文件而不用鼠標點來點去,是不是會很方便呢?這個非常容易:只需要使用command+shift+o鍵就可以彈出一個對話框,然后在這個對話框中搜索欄中輸入開發者看到的頭文件名,然后在下面彈出來的信息中選取適合的文件即可查看此文件內容.
9.書簽:在Xcode中與許開發者在代碼中插入書簽,在代碼中可能又一些需要引起人們注意的地方,如:在代碼某一個區域以后需要修改優化等操作的話,那么開發者在這里做一個標記的話,到動手操作的時候就可以快速定位此處了。做法為:首先在源文件中放入插入點或者選定一個文本區域,然后選中Edit->Add to Bookmarks,或者使用默認的快捷鍵command+D(與Safari中的一樣),最后當出現提示的時候,輸入書簽名稱即可.
10.集中注意力:緊挨着源代碼的左邊又兩個空列,它們當中左邊較寬的一列叫做邊列(gutter),靠右較窄的一列叫做焦點列(focus ribbon):焦點列的作用能夠讓開發者在瀏覽代碼段時集中注意力.焦點列的灰度:代碼嵌套得越深,在它旁邊的焦點列中,灰色也會越深.這種顏色編碼能夠使代碼的復雜程度一目了然.用鼠標懸停在焦點列上時會突出顯示相應的代碼段,也可以點擊焦點列來折疊相應的代碼段。
11.開啟導航條:在代碼編輯器的頂部右一個小控件條,也就是導航條.這里面的很多控件可以讓開發者快速地在項目中的源文件之間進行切換.關於#pragma的說明:“Pragma”源自希臘單詞,意思是“行動”.#pragma指令將Objective-C常規代碼之外的信息或說明傳遞給編輯器和代碼編輯器.通常,Pragma是被忽略的,但它在一些軟件開發工具中可能有其他含義,如果某個工具並不知道pragma是什么,則應該“點頭微笑”並且忽略它,而不是生成警告或錯誤信息.
12.研究助手(Research Assistant)的浮動小窗口會根據逆在Xcode力的交互操作來更新所顯示它的內容,要打開研究助手,選擇菜單Help->Show Show Research Assistant。
13.文檔管理程序:開發者想直接訪問蘋果公司官方API文檔,最快的方法是按住Option鍵並雙擊某個符號,這是查找該符號相關文檔的快捷方式.需要在Xcode其他窗口甚至是網頁瀏覽器中打開文檔也很容易,只需要按住control鍵並單擊(或右鍵單擊)文檔區域來打開菜單即可.
14.調試:系統的在代碼中查找程序哪里出錯的過程叫做調試(debugging)。
15.暴力調試:最簡單的調試方式就是暴力調試,暴力調試是指在程序中放入輸出語句(如NSLog)來輸出程序的控制流程和一些數據值.
16.Xcode調試器:Xcode還有一個調試器,調試器是位於開發者編寫的程序和操作之間的程序,它能夠中斷開發者的程序,使之在運行中停止.這樣就可移檢查程序的數據及其修改程序.開發者也可以單不執行逐行進行檢查程序.說明:Xcode使用的調試器就是GDB,GDB是GNU項目的一部分,它可以在很多不同平台上使用.若開發者願意,也可以通過命令行來運行它,GDB有者完善的文檔系統,盡管它的文檔有些難於理解並且網絡上流傳者好幾個版本的GDB教程.
17.精巧的調試符號:打算調試程序時,需要確保開發者正在使用Debug生成配置.可以通過Xcode工具欄中的彈出菜單Active Build Configuration來檢驗.Debug配置告訴編輯器發出額外的調試器符號,而調試器通過這些符號可以知道程序在什么地方都有寫什么.同時,還要確認程序是用調試器來運行的,在Xcode里有兩種運行程序的方法,選擇菜單Run->Run或者按快捷鍵command+R,將會不使用調試器運行程序,若要使用調試器,選擇菜單Run->Go(Debug)、Run->Debug,或者按快捷鍵command+Y.說明:多線程編程是一種同時處理多個執行流的編程方式,正確應用它是很困難的,通常,多線程編程所產生的錯誤非常難於找到,如果有人告訴你多線程很容易,那么他們不是被騙了或者試圖向你推銷什么東西。下面介紹是4個控件:第一個控件看起來cd機的開始按鈕.,安繼續鍵可以使用command+option+p。單擊它之后,程序會接着運行到遇見下一個斷點,然后結束或者崩潰.第二個控件看起像跳過按鈕使用的快捷鍵是command+option+O.單擊這個控件之后它就會執行下一行,然后又會吧程序控制權交還給開發者,第三個按鈕,向下指向一個點的箭頭,它是跳入按鈕(也可以使用快捷鍵:鍵盤右上角的鍵+command+I),這個按鍵的功能就是跳入方法內部,顯示其代碼,最后箭頭設置在代碼的起始位置.第四個按鈕是跳出按鈕,快捷鍵是command+右上角的鍵+T,單擊它會終止當前運行的函數並且程序會停在調用程序的下一行代碼.若是在試驗當中,那么就沒有必要在試驗當中按這個鍵了。再下一個按鈕(又一個噴霧罐的方框)是用來打開Xcode調試窗口的,再下一個按鈕用來打開GDB控制台,開發者可以再這個調試器種直接輸入調試命令.最后一個控件是顯示調用棧的彈出菜單,調用棧是當前處於活動狀態的函數的集合,如果A調用B,B調用C,那么C就位於棧的頂部.再更為復雜的程序中,這種調用棧也稱為棧跟蹤。
18.檢查程序:當開發者在程序的某個部分設置斷點或者分步執行時,說明開發者向了解程序狀態--變量的值.在Xcode種又數據提示功能.
第八章節-Foundation Kit快速教程:
Cocoa的框架由兩個不同的框架組成的:Foundation Kit和Application Kit組成,后者包含了所有的用戶接口對象和高級類.main()函數的創建通過alloc、初始化通過init
1.有用的數據類型:a.范圍的作用、b.幾何數據類型。a.第一個結構體是NSRange,第一種是直接給自段賦值;第二種是應用c語言的聚合結構賦值機制;第三種是Cocoa提供的快捷函數NSMakeRange();如:x.NSRange range;range = 17;range = 4;y.NSRange range = {17,4};z.NSRange range = NSMakeRange(13,15);b.NSPoint來表示一個點,NSSize來儲存長度和寬度.Cocoa提供一個由點和大小復合而成的矩形函數數據類型:其快捷函數為:NSMakePoint();NSMakeSize();和NSMakeRect();這里需要說明:Cocoa的這些數據類型是C的struct類型而不是對象呢?原因歸結起來就是因為性能。程序(尤其是GUI程序)會用到許多臨時的點、大小和矩形來完成他們的工作,還記得吧,所有的Objective-C對象都是動態分配的,而動態分配是一個代價較高的操作,它會消耗大量的時間,所以將這些結構創建成第一等級的對象都會在使用過程種增加大量的系統開銷.
2.字符串:Cocoa種的NSString有很多內置方法,讓字符串個的處理邊的簡單很多.a.創建字符串,通過接受格式字符串和一些參數來輸出格式話的結果NSString和stringWithFormat:方法就是通過格式字符串和參數來創建NSString的;b.類方法,;c.關於大小、d.比較策略、e.不區分大小寫的比較、f.字符串內是否還包含別的字符串.
4.字典NSDictionary:字典就是關鍵字及其定義的集合。Cocoa種有一個實現這種功能的集合類NSDictionary.NSDictionary在給定的關鍵字(通常是一個NSString字符串)下存儲一個數值(可以是任何類型的對象)。然后開發者就可以用這個關鍵字來查找相應的數值,所以開發者有一個存儲了某人所有聯系信息的NSDictionary.那么開發者就可以對這個字典說,“給出關鍵字home-address下的值”,說明:字典(也被稱為散列表或者關聯數組)使用的是鍵查詢的優化存儲方式,它可以立即找出要查詢的數據,而不需要便利整個數組進行查找,對於頻繁的查詢和大型的數據集來說,使用字典比數組要快得多,實際上字典非常快。
