第十八章:Image和鼠標事件程序員
1.NSResponder
NSView繼承自NSResponder類。全部的事件處理方法都定義在NSResponder類中。NSResponder申明瞭以下方法:
- (void)mouseDown:(NSEvent *)theEvent;
- (void)rightMouseDown:(NSEvent *)theEvent;
- (void)otherMouseDown:(NSEvent *)theEvent;web
- (void)mouseUp:(NSEvent *)theEvent;
- (void)rightMouseUp:(NSEvent *)theEvent;
- (void)otherMouseUp:(NSEvent *)theEvent;數組
- (void)mouseDragged:(NSEvent *)theEvent;
- (void)scrollWheel:(NSEvent *)theEvent;
- (void)rightMouseDragged:(NSEvent *)theEvent;
- (void)otherMouseDragged:(NSEvent *)theEvent;網絡
2.NSEvent:一個事件對象包含了全部激發該事件的相關信息。當處理一個鼠標事件時,你應該會對這個方法感興趣:
- (NSPoint)locationInWindow;//返回事件發生的位置
- (unsigned int)modifierFlags;//返回的整型數告訴你,用戶按住了鍵盤上哪個修飾鍵。這讓程序員得到如Control-click和Shift-click的組合點擊事件:多線程
- (void)mouseDown:(NSEvent*)e { unsigned int flags; flags = [e modifierFlags]; if (flags & NSControlKeyMask){ ...handle control click... } if (flags & NSShiftKeyMask){ ...handle shift click... } }
下面是一些常量,通常對這些修飾標記取AND(&):
NSShiftKeyMask、NSControlKeyMask、NSAlertnateKeyMask、NSCommandKeyMask框架
- (NSTimeInterval)timestamp;//此方法返回一個按秒計量的時間值,指的是從機器啓動開始,到該事件發送時的時間量。NSTimeInterval爲double類型
- (NSWindow*)window;//返回發送事件的窗口
- (int)clickCount;//單擊、雙擊仍是3擊
- (float)pressure;//若是用戶使用一個壓力輸入設備,返回壓力值socket
- (float)deltaX;
- (float)deltaY;
- (float)deltaZ;//這三個方法得到鼠標或滾輪的位置改變量函數
3.獲取鼠標事件——必須在.m文件中重載鼠標事件方法oop
4.View的座標系統
若是有兩個view,a和b,要將NSPoint p 從b的座標系統轉換到a的座標系統,能夠這樣:
NSPoint q = [a coverntPoint:p fromView:b];//若是b爲空,將從窗口的座標系統轉換到a的座標系統佈局
第十九章:鍵盤事件
1.NSResponder
- (BOOL)acceptsFirstResponder;//將被子類重載,假如須要處理鍵盤事件則返回YES
- (BOOL)resignFirstResponder;//詢問接收對象是否要放棄first-responder狀態
- (BOOL)becomeFirstResponder;//通知接收對象成爲窗口的first-responder
- (void)keyDown:(NSEvent *)theEvent;//通知接收對象,用戶按住了某個鍵
- (void)keyUp:(NSEvent*)theEvent;
- (void)flagsChanged:(NSEvent*)theEvent;//通知接收對象用戶按住或放開了一個修飾鍵(如Shift或Control)
2.NSEvent——如下一般是用在得到鍵盤事件信息的方法:
- (NSString *)characters;//返回事件生成的字符
- (BOOL)isARepeat;//當用戶按住某鍵產生重複的鍵盤事件時返回YES,對於新的鍵盤事件則返回NO
- (unsigned short)keyCode;//返回事件對應的鍵盤某個鍵的編碼
- (unsigned int)modifierFlags;//返回一個整型位數來指示對應的修飾鍵的情況
第二十章:繪製帶屬性的文本
1.NSFont。NSFont類只有兩種類型的方法:
a.獲得想要字體的類方法
b.獲得字體尺度的方法,如字符的高度
經常使用方法:
+ (NSFont *)fontWithName:(NSString *)fontName size:(float)fontSize;//fontName是family-face名稱。fontSize若是設爲0.0,就使用默認的用戶字體大小
//下面這些方法返回相對應類型的用戶默認字體。若是fontsize爲0.0,就使用默認大小
+ (NSFont *)userFixedPitchFontOfSize:(float)fontSize;
+ (NSFont *)userFontOfSize:(float)fontSize;
+ (NSFont *)messageFontOfSize:(float)fontSize;
+ (NSFont *)toolTipsFontOfSize:(float)fontSize;
+ (NSFont *)titleBarFontOfSize:(float)fontSize;
2.NSAttributedString
有時候你但願字符串中的某些字符使用特定的屬性來顯示。例如,你要顯示「Big Nerd Ranch」,並但願給0到2的字符加上下劃線,0到7的字符爲綠色,9到13的字符顯示爲下標
Cocoa使用結構NSRange來處理區間。它包含兩個整型類型成員—location和length
爲了建立特定區間爲效果字符的字符串,可使用Cocoa類NSAttributedString和NSMutableAttributedString:
NSMutableAttributedString *s; s = [[NSMutableAttributedString alloc] initWithString:@"Big Nerd Ranch"]; [s addAttribute:NSFontAttributeName value:[NSFont userFontOfSize:22 range:NSMakeRange(0,14)]; [s addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:1] range:NSMakeRange(0,3)]; [s addAttribute:NSForegroundColorAttributeName value:[NSColor greenColor] range:NSMakeRange(0,8)]; [s addAttribute:NSSuperscriptAttributeName value:[NSNumber numberWithInt:-1] range:NSMakeRange(9,5)]; //一旦有了一個屬性字符串,就能夠給它添加不少要素 [s drawInRect:[self bounds]]; //將它設置給文本框 [textField setAttributedStringValue:s]; //將它設置給按鈕 [button setAttributedTitle:s];
NSAttributedString能夠讀寫下面的文件格式:
String:讀取一個文本文件
RTF:Rich Text格式是多樣字體、多樣顏色的文本標準。你能夠經過NSData對象來讀取或設置屬性字符串的內容
RTFD:帶有附件的RTF,能夠包含圖片
HTML:屬性字符串能夠進行基本的HTML佈局,不過最好使用webview
Word:屬性字符串能夠讀寫簡單地.doc文件
OpenOffice
3.繪製字符串和屬性字符串
NSAttributedString:
- (void)drawAtPoint:(NSPoint)aPoint;//繪製字符串,aPoint爲字符串的左下角
- (void)drawInRect:(NSRect)rect;//繪製字符串。全部的繪製動做都再rect內部,若是rect裝不下,字符串會被裁剪
- (NSSize)size;//返回將會繪製的大小
NSString:
- (void)drawAtPoint:(NSPoint)aPoint withAttributes:(NSDictionary *)attribs//繪製帶有attribs屬性的字符串
- (void)drawInRect:(NSRect)aRect withAttributes:(NSDictionary *)attribs;
- (NSSize)sizeWithAttributes:(NSDictionary *)attribs;//返回使用屬性attribs繪製時所需大小
4.讓你的View生成PDF數據
全部的繪製命令均可以經過AppKit框架轉換到PDF中。PDF數據能夠發生給文件或打印機
你建立一個view,view知道怎麼生成pdf數據來描述本身的內容:
- (NSData *)dataWithPDFInisdeRect:(NSRect)aRect;//這個方法會先建立一個數據對象,而後調用drawRect方法。這時這些繪製命令都會繪製到數據對象中,而再也不是一般的屏幕。有了數據對象,只須要簡單地將它保存到一個文件中
5.NSFontManager:能夠顯示字體爲粗體、斜體或壓縮等等
第二十一章:粘貼板和Nil-Targeted Actions
1.粘貼板服務(pasteboard server)(usr/bin/pboard)是Mac系統上運行的一個進程。應用程序使用NSPasteboard類寫入數據到該進程,或者從該進程讀取數據。粘貼板服務讓不一樣應用程序之間的複製、剪切、粘貼成爲可能
NSPasteboard類做爲粘貼板服務的接口,下面是它經常使用的方法:
+ (NSPasteboard *)generalPasteboard;//返回常規的NSPasteboard,你將使用這個粘貼板複製、剪切和粘貼
+ (NSPasteboard *)pasteboardWithName:(NSString*)name;//根據名稱返回某個粘貼板
- (int)declareTypes:(NSArray *)types owner:(id)theOwner;//清空粘貼板中得數據,並聲明調theOwner複製到粘貼板中得數據的類型
//寫輸入到粘貼板
- (BOOL)setData:(NSData *)aData forType:(NSString *)dataType;
- (BOOL)setString:(NSString *)s forType:(NSString *)dataType;
- (NSArray *)types;//返回一個數組,包含能夠從粘貼板中讀取的數據類型
- (NSString *)availableTypeFromArray:(NSArray *)types;//返回粘貼板所能提供的全部數據類型中得第一個
//從粘貼板讀取數據
- (NSData *)dataForType:(NSString *)dataType;
- (NSString *)stringForType:(NSString *)dataType;
2.Nil-Targeted Actions
在衆多視圖中,如何正確地發送cut:、copy:或者paste:消息?——nil-targeted actions
若是一個控件的target爲空,應用程序則嘗試發送action消息給多個對象,直到它們中的一個有響應。應用程序首先嚐試給key window的first responder發送消息
NSView、NSApplication和NSWindow都是繼承自NSResponder,它們都有一個實例變量叫nextResponder。若是一個對象不響應nil-targeted acion,它的nextResponder就獲得一個機會。
視圖的nextResponder一般是它的父視圖。window的content view 的nextResponder就是window。所以把responder連接在一塊兒就是響應鏈(向上回溯)
如何搜索響應鏈
1)keyWindow的firstResponder以及它的響應鏈。響應鏈通常包括父視圖以及最終的key window
2)key window的委託
3)若是它是一個文檔應用,還包括NSWindowController和key window的NSDocument對象
4)若是main window和key window不一樣,它還有例行對main window依次檢查一遍:
a.main window的firstResponder以及它的響應鏈,包括main window本身
b.main window的委託
c.NSWindowController和main window的NSDocument對象
5)NSApplication的實例
6)NSApplication的委託
7)NSDocumentController
響應鏈就是這一系列的對象。對象依次被詢問可否響應nil-targeted action
咱們知道給nil發送一個消息是不會發生任何事情的。事實上,全部的target/action消息都由NSApplication處理,它又下面這個方法:
- (BOOL)sendAction:(SEL)anAction to:(id)aTarget from:(id)sender;
當target爲空時,NSApplication就知道要嘗試給響應鏈上的對象發送消息了
第二十二章:Categories
1.給NSString添加一個方法
#import <Foundation/Foundation.h> @interface NSString (FirstLetter) - (NSString*)BNR_firstLetter; @end ------------------------ #import "FirstLetter.h" @implementation NSString (FirstLetter) - (NSString *)BNR_firstLetter { if ([self length] < 2){ return self; } NSRange r; r.location = 0; r.length = 1; return [self substringWithRange:r]; } @end
2.聲明私有方法
3.Protocol的非正式寫法
第二十三章:拖放
第二十四章:NSTimer
1.NSButton的實例有一個target和一個action(selector)。當按鈕按下時,就發送action消息給target。
Timer以相同的方式工做。Timer對象有一個target、一個selector、一個以秒爲單位的延時。延時結束後,target會收到selector消息。Timer本身就是消息的參數
2.NSRunLoop
NSRunLoop對象專司等待。它等待事件抵達,而後把事件中轉給NSApplication;它等待timer事件,而後把事件中轉給NSTimer。你甚至能夠附加一個網絡socket到循環中,而後它就會等待那個socket上數據的抵達
第二十五章:工做表
1.一個工做表就是一個NSWindow實例,它附屬於另一個窗口。工做表覆蓋在窗口上,窗口中止接受事件,直到工做表消失。
NSApplication有下面幾個方法來處理工做表:
//啓用一個工做表
- (void)beginSheet:(NSWindow *)sheet modalForWindow:(NSWindow *)docWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contentInfo:(void*)contextInfo
//結束一個工做表
- (void)endSheet:(NSWindow*)sheet returnCode:(int)returnCode;
2.窗口模式
激活一個工做表後,用戶就不能發送事件到宿主窗口。當警告面板(Alert Panel)運行時,它就是模式窗口——即阻止用戶給任意其餘窗口發送事件:
- (int)runModalForWindow:(NSWindow *)aWindow;//只有發送給aWindow的的事件纔會經過這個方法。而要讓aWindow成爲非模式窗口,可給NSApplication對象發送這個消息:
- (void)stopModalWithCode:(int)returnCode;
第二十六章:建立NSFormatter
1.格式化器 接受一個字符串的輸入,生成另一個對象。如當輸入字符串「3/17/1975」,NSDataFormatter就把它轉換爲一個1975年3月17日的NSData對象
一個格式化器也能夠接受一個對象的輸入,而後生成一個用於顯示的字符串。例如,文本框有一個NSDataFormatter,當文本框收到setObjectValue:的消息,消息參數是一個NSCalendarDate對象,date格式化器就會建立一個字符串表明那個日期,而後用戶就看到那個字符串
全部的格式化器都是NSFormatter的子類。Cocoa自帶兩個子類:NSDateFormatter和NSNumberFormatter
大多數基礎格式化器都要實現兩個方法:
//用戶輸入時,控制器(如文本框)要把一個字符串轉換爲一個對象,它給格式化器發送這個消息。格式化器能夠返回YES並把anObject設置爲指向新對象的指針。
//若是返回NO,字符串不會被轉換,同時設置errorPtr,指出差錯所在,errorPtr是一個指向指針的指針。也就是說他是一個讓你能夠放置一個指向字符串的指針的地方
- (BOOL)getObjectValue:(id*)anObject forString:(NSString *)aString errorDescription:(NSString *)errorPtr;
2.NSControl的委託
在格式化失敗後,綁定機制會產生一個警告框。格式化失敗也會通知文本框的委託。若是格式化器認爲字符串是無效的,委託就會收到下面的報錯信息:
- (BOOL)control:(NSControl *)control didFailToFormatString:(NSString *)string errorDescription:(NSString *)error;
3.讓格式化器返回Attributed字符串——能讓格式化器不只能決定要顯示什麼字符串,還能決定如何顯示它們:
- (NSAttributedString *)attributedStringForObjectValue:(id)anObj withDefaultAttributes:(NSDictionary *)aDict;
第二十七章:打印
1.處理分頁
在你的視圖中重載下面的兩個方法:
- (BOOL)knowsPageRange:(NSRange *)rptr;//有多少頁
- (NSRect)rectForPage:(int)pageNum;//每個頁的位置
第二十八章:Web Service
1.Web Service說到底不過是攜帶着XML數據的HTTP請求(request)和響應(response)而已
HTTP的請求和響應由NSURL、NSURLRequest、NSURLConnection處理。生成以及解析XML通常由NSXMLDocument和NSXMLNode負責
第二十九章:視圖切換
1.相比生成一個新窗口,更常見的狀況是用一個視圖替換另一個視圖。一個容易的實現方法就是改變box的content view
第三十章:Core Data Relationships
第三十一章:垃圾收集
1.若是僅使用Object-c對象,垃圾收集器能夠精準的完成它的工做。可是,只要開始 malloc C數據類型以及Core Foundation structures,就要當心了
當垃圾收集器運行時,它會檢索不可到達的對象。你能夠把程序中的對象當作一個有向圖:這個對象知道那個對象;它知道一些對象,而後這些對象又知道其餘的對象,因此垃圾收集器從棧中的指針以及全局變量開始,遍歷整個有向圖,直到它記下全部的「可到達」對象。不可到達的對象被釋放。
2.非對象的數據類型
a. C的原始類型
若是有一個整數緩衝區,當它不可到達時你想讓垃圾收集器釋放它,這裏有一個替代 malloc() 的方法:
int *intBuff = NSAllocateCollectable(100*sizeof(int),0);
當一個「知道」另一個對象,咱們說它有一個引用。引用能夠是強或者是弱。垃圾收集器會注意強引用,但會忽略弱引用。所以若是咱們只有一個弱引用指向intBuff,它將當即被垃圾收集器釋放
弱引用:有時咱們須要一個對象指針,只要整個對象存在就一直指向它,但又不想由於這個指針的緣由致使整個對象沒法被垃圾收集器回傳,這種狀況使用弱引用
儘管指針還指向這個對象,垃圾收集器仍是會釋放這個對象。若是指針指向一個已經被釋放的對象,它會自動被設置爲nil
b.Core Foundation
第三十二章:Core Animation
1.CALayer——可被視爲一個供繪製的緩衝區。layer也像視圖那樣以必定層次結構組織。視圖被一個層(layer)覆蓋,而後這個層還能夠有子層
一旦有了能夠高速操縱的CALayer,咱們就須要一些東西來驅動這個過程。而CAAnimation就是。NSAnimationContext用來羣組以及同步多個animation
常見子類:
CATextLayer:能夠更方便地在layer上繪製文本
CAOpenGLLayer:能夠更方便調用OpenGL
視圖的base layer是_NSViewBackingLayer的實例(不是一個公共類),知道如何繪製它上面的視圖的內容
第三十三章:一個簡單地Cocoa/OpenGL應用程序
1.NSOpenGLView是NSview的一個子類,有一個OpenGL的繪圖上下文。NSOpenGLView的一些重要方法:
- (id)initWithFrame:(NSRect)frameRect pixelFormat:(NSOpenGLPixelFormat *)format;//指定的初始化方法
- (NSOpenGLContext *)openGLContext;//返回視圖的OpenGL上下文
- (void)reshape;//當視圖調整大小時被調用。這個方法被調用時,OpenGL的上下文是活動的
- (void)drawRect:(NSRect)r;//當視圖須要重繪時調用它。這個方法被調用時,OpenGL的上下文是活動的
第三十四章:NSTask
1.你建立的每個應用都是一個目錄,目錄裏的某處有個可執行文件。要在一個Unix系統上(如Mac)運行可執行程序,首先會fork出一個進程,而後在新進程中執行文件中的代碼。
NSTask是一個爲了便於使用Unix的fork()和exec()函數的包裝器,經過指定一個可執行文件的路徑並啓動它。不少進程是從標準輸入(standard-in)中讀取數據並寫回到標準輸出(standard-out)和標準錯誤(standard-error)中,應用程序能夠用NSTask附加管道(pipe)到外部進程上讀取或發送數據,NSPipe類表示管道
2.多線程對多進程