幾個新類型:
http://blog.chinaunix.net/u3/104182/showart_2248115.html
1. Target-Action 模式
NSObject performSelector:@selector()... 類似函數指標的用法. 但它傳遞參數有限. 可能使用協議可替代,並且可以增加代碼清晰度.
它有一個waitUntilDone的參數,可以設定是非同步還是同步執行方法.
使用函數指標獲得極大的動態性, 但是付出的代價就是編譯器不知道我們要執行哪一個方法,所以在編譯的時候不會找出錯誤,只有執行的時候才知道函數指標是否正確。
Target-Action Paradigm 完全是物件導向的事件傳遞機制。運行時,通過respondsToSelector: 方法來檢查實現的情況。如果有實現,那麼使用performSelector:withObject:來調用具體的Action。
2.通知是一種對象間通訊的輕量級機制.
[[NSNotificationCenter defaultCenter] addObserver... ];註冊或訂閱訊息,可以訂閱自訂的或系統的訊息.
[[NSNotificationCenter defaultCenter] postNotificationName... ]; 發送同步訊息
系統訊息如:UIApplicationWillTerminateNotification
訊息響應函數使用NSNotification作為參數.
對同一個訊息註冊多次,則發送訊息時,會響應多次。
3. Protocal 協議,類似於介面的用法.
4. @select()
在Objective-C裡,方法的名字包含了方法名和第一個參數的冒號,以及後面所有參數的參數標識加上相應的冒號,如果沒有參數就不加冒號。
-(void)foo:(id)bar withFoo1:(id)bar1
{
}
這個方法真實的名字是 foo:withFoo1:
5.Objective C中的少用函數調用的概念,而是用對象之間“訊息”的傳遞(messaging)來代替.
ObjC中是以訊息機制來工作的. 諸如-(void)foo:(int)a的語句在編譯時間被 objc_msgSend(receiver,selector,arg1,arg2,….)替換了,其實每一條發送訊息的代碼本質上還是調用函數 (call function),不過他們調用的都是同一個函數objc_msgSend,也可能是objc_msgSend_stret(傳回值是結構體),objc_msgSend_fpret(傳回值是浮點型)等.
分析objc_msgSend(receiver,selector,arg1,arg2,….)的參數,第一個receiver的類型是id,代表接受訊息的對象, 第二個是selector代表接收對象的方法,後面的是該方法的參數. [theClass foo:10]被編譯成objc_msg(theClass,@selector(foo:),10);
它的實現是基於ObjC runtime. NSObject類實現了這套機制,所以每一個繼承於NSObject的類都能自動獲得runtime的支援。在這樣的類中,有一個isa指標,指向該類定義的資料結構體,這個結構體是由編譯器在編譯時間為類(須繼承於NSObject)建立的.在這個結構體中有包括了指向其父類類定義的指標以及Dispatch table. Dispatch table是一張SEL和IMP的對應表。對於名稱相同的方法,他們都有相同的SEL,方法的名稱不包括類名稱,所以子類和父類中的同名方法擁有相同的SEL,但是他們的實現可以各不相同,因而在他們各自的Dispatch表中SEL所對應的IMP是不同的,IMP是一個函數指標,而雖然每一個SEL對應的是一個方法的名稱,但考慮到效率,SEL本身是一個整型,編譯器會另外產生一張SEL和方法名稱對應的表。有了這樣的結構,objc就可以實現多態了。
6.動態給類增加訊息.
7.
Delegate:
訊息的寄件者(sender)告知接收者(receiver)某個事件將要發生,delegate同意然然後寄件者響應事件,delegate機制使得接收者可以改變寄件者的行為。通常寄件者和接收者的關係是直接的一對多的關係。
Notification:
訊息的寄件者告知接收者事件已經發生或者將要發送,僅此而已,接收者並不能反過來影響寄件者的行為。通常寄件者和接收者的關係是間接的多對多關係。
Notification是廣播。
Delegate是點對點。
9.NSInvocation
10.模組間協作,盡量不使用target-action模式,慎用通知,優先使用代理。
11.KVO=KeyValue Observing,KVC=Key Value Coding
Kvo是Cocoa的一個重要機制,他提供了觀察某一屬性變化的方法,極大的簡化了代碼。這種觀察-被觀察模型適用於這樣的情況,比方說根據A(資料類)的某個屬性值變化,B(view類)中的某個屬性做出相應變化。對於推崇MVC的cocoa而言,kvo應用的地方非常廣泛。(這樣的機制聽起來類似Notification,但是notification是需要一個發送notification的對象,一般是notificationCenter,來通知觀察者。而kvo是直接通知到觀察對象。)
http://www.cnblogs.com/scorpiozj/archive/2011/03/14/1983643.html
例:
Student *stu = [[Student alloc]init];
[stu addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
stu.name = @"張三";
stu.name值改變時,會調用下面的方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"keyPath:%@ object:%@ change:%@",keyPath,object,change);
}
http://hi.baidu.com/492437598/blog/item/6ed35079c748e7f52f73b380.html
12.應用之間調用
http://blog.csdn.net/pjk1129/article/details/6641211
http://blog.csdn.net/pjk1129/article/details/6643411
跳轉到appstore:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms://itunes.apple.com/app/sandman/id388887746?mt=8&uo=4"]];
或者
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms-apps://itunes.apple.com/app/sandman/id388887746?mt=8&uo=4"]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms-apps://itunes.apple.com/app/hainan-tianya-online-network/id451916383?mt=8&uo=4"]];
後者直接開啟app store
當在手機上的網頁中的連結有http://itunes.apple.com/app...時,需要把http替換成itms-apps,然後使用上面的方式跳到appstore中。
跳轉到評分:
在應用中加入打分按鈕,點擊後直接跳轉到 App Store 的評分介面,可以解決在使用者用了好軟體後忘記或嫌麻煩而不去 App Store 進行打分評星。
App Store 上評論的連結地址是 itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id = appleID
NSString* appleid=@"451916383";
NSString *str = [NSString stringWithFormat:
@"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%@",
appleid ];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];
ios或mac程式中添加連結到評價頁面的方法
http://blog.csdn.net/terrytan18/article/details/7377836
13. 開啟documents下的檔案,或包中的資源檔。
用瀏覽器開啟word
NSString *path = @"/..../xx.doc";
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
在SDK中開啟其他接入應用的解決方案
http://blog.csdn.net/arthurchenjs/article/details/6920631
應用程式間通訊 - URL Scheme
http://blog.csdn.net/flower4wine/article/details/6454957
在Mac和iOS中註冊自訂的URL Scheme
http://cocoa.venj.me/blog/custom-url-scheme-on-mac-and-ios/
iOS應用中開啟一些其他應用的URL-Scheme
http://willonboy.tk/?p=742
iPhone開發技巧 URL Scheme啟動進程調試教程
http://mobile.51cto.com/iphone-278973.htm
請問程式中如何調用safari來開啟本地html檔案。未有答案。
http://www.cocoachina.com/bbs/read.php?tid=17135&page=1
13.1 UIDocumentInteractionController 用真機測試,模擬器可能不起作用。
UIDocumentInteractionController uses QLPreviewController to display. It allows for additional hooks for delegate methods.
#pragma mark -
#pragma mark loadDocument
-(void)loadDocument:(NSString*)path
{
/*
//use UIWebView
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
if(!iWebView)
{
iWebView=[[UIWebView alloc] initWithFrame:self.view.bounds];
iWebView.scalesPageToFit = YES;
for (id subview in iWebView.subviews)
{
if ([[subview class] isSubclassOfClass: [UIScrollView class]])
{
((UIScrollView *)subview).bounces = NO;
}
}
[self.view addSubview:iWebView];
}
[iWebView loadRequest:request];
*/
//use UIDocumentInteractionController
NSURL *url = [NSURL fileURLWithPath:path];
UIDocumentInteractionController* controller = [[UIDocumentInteractionController interactionControllerWithURL:url] retain];
controller.delegate = self;
BOOL ret = [controller presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];//documentInteractionControllerDidDismissOpenInMenu
if (!ret)
{
ret = [controller presentPreviewAnimated:YES];//documentInteractionControllerDidEndPreview
if (!ret)
{
[DialogUtil postAlertWithMessage:@"open failed"];
}
}
}
#pragma mark -
#pragma mark UIDocumentInteractionControllerDelegate
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
{
return self;
}
- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller
{
NSLog(@"documentInteractionControllerDidEndPreview");
[controller autorelease];
}
- (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller
{
NSLog(@"documentInteractionControllerDidDismissOpenInMenu");
[controller autorelease];
}
13.2 結果是用canOpenURL不能開啟本地檔案
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@",path]];
BOOL ret=[[UIApplication sharedApplication] canOpenURL:url];
if(ret)
{
ret=[[UIApplication sharedApplication] openURL:url];
NSLog(@"canOpenURL");
if(!ret)
{
[DialogUtil postAlertWithMessage:[NSString stringWithFormat:@"open %@ failed",[url absoluteString]]];
}
}
else
{
[DialogUtil postAlertWithMessage:[NSString stringWithFormat:@"can't open %@",[url absoluteString]]];
}
13.3 畫PDF使用QurtZ的CGPDFDocumentGetPage,CGContextDrawPDFPage等相關API。
13.4 iPhone上看Word、Excel、PDF全攻略
http://iphone.tgbus.com/tutorial/use/200801/20080102113010.shtml
13.5 iOS中使用QLPreviewController來預覽檔案
http://www.acwind.net/blog/?p=1267
QuickLook.framework
#import <QuickLook/QLPreviewController.h>
if([QLPreviewController canPreviewItem:(id <QLPreviewItem>)localFileUrl])
{
QLPreviewController* previewController=[[QLPreviewController alloc] init];
previewController.dataSource=self;
[viewController presentModalViewController:previewController animated:YES];
[previewController release];
}
#pragma mark -
#pragma mark QLPreviewControllerDataSource
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller;
{
return 1;
}
- (id)previewController:(QLPreviewController *)previewController previewItemAtIndex:(NSInteger)idx
{
NSURL* url=previewItemURL_;
return url;
}
14.http://tiny4cocoa.com/thread-1963-1-1.html
在 iOS中可以直接調用 某個對象的訊息 方式有2中
一種是performSelector:withObject:
再一種就是NSInvocation
第一種方式比較簡單,能完成簡單的調用。但是對於>2個的參數或者有傳回值的處理,那就需要做些額外工作才能搞定。那麼在這種情況下,我們就可以使用NSInvocation來進行這些相對複雜的操作
NSInvocation可以處理參數、傳回值。會java的人都知道凡是操作,其實NSInvocation就相當於反射操作。