日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

迷惑新手的IOS开发问题

發布時間:2024/1/8 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 迷惑新手的IOS开发问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

十個很不錯的迷惑新手的Cocoa,OC開發問題總結,適合大家進行注意和學習。

在你繼續深入學習之前,請停下腳步弄清這些問題。如果你是新手,這個教程不要希望一次能看的非常透徹,學一定階段反回來再看看又會有新的體會的。對于完全看不懂的同學,也不要強求自己。找來《計算機組成原理》《數據結構》《操作系統》《編譯原理》《計算機網絡》之類的大學課本看看吧。這些基礎不可能在這個論壇學到的,至少不可能系統的學到。?
?
1. language background?
?
首先c, c++語言背景,必須。?
很多人問 “沒有任何語言基礎,我不想學c直接學objective-c”?
這里簡單幾句,objc 90%代碼是c、眾多開源代碼是c,c++。你不學好c在unix世界里只能是個二流開發者!也許說得過于嚴厲,不過自己斟酌把。??
?
接著English必須。?
需要英語!需要英語!需要英語!蘋果不會把它們文檔都寫成中文的?!笆裁?#xff0c;有人翻譯?” 等有人閑著翻譯出來了的時候,大家都已經賣了很多軟件了。你也是跟著人家屁股后面做開發。?
?
2. Runtime(運行時)?
?
Objective-c是動態語言,??很多新手或者開發人員常常被Runtime這個東西所迷惑。而恰恰這是一個非常重要的概念。 為什么重要呢!?我可以這么問:“如果讓你(設計、)實現一個計算機語言,你要如何下手?” 很少程序員這么思考過。但是這么一問,就會強迫你從更高層次思考(1)以前的問題了。 注意我這句話‘設計’括起來了,稍微次要點,關鍵是實現。?
?
我把實現分成3鐘不同的層次:?

1. 傳統的面向過程的語言開發,例如c語言。實現c語言編譯器很簡單,只要按照語法規則實現一個LALR語法分析器就可以了,編譯器優化是非常難的topic,不在這里討論范圍內,忽略。 這里我們實現了編譯器其中最最基礎和原始的目標之一就是把一份代碼里的函數名稱,轉化成一個相對內存地址,把調用這個函數的語句轉換成一個jmp跳轉指令。在程序開始運行時候,調用語句可以正確跳轉到對應的函數地址。 這樣很好,也很直白,但是。。。太死板了。everything is pre-determined?
?
????2. 我們希望靈活,于是需要開發面向對象的語言,例如c++。 c++在c的基礎上增加了類的部分。但這到底意味著什么呢?我們再寫它的編譯器要如何考慮呢?其實,就是讓編譯器多繞個彎,在嚴格的c編譯器上增加一層類處理的機制,把一個函數限制在它處在的class環境里,每次請求一個函數調用,先找到它的對象, 其類型,返回值,參數等等,確定了這些后再jmp跳轉到需要的函數。這樣很多程序增加了靈活性同樣一個函數調用會根據請求參數和類的環境返回完全不同的結果。增加類機制后,就模擬了現實世界的抽象模式,不同的對象有不同的屬性和方法。同樣的方法,不同的類有不同的行為! 這里大家就可以看到作為一個編譯器開發者都做了哪些進一步的思考。但是。。。還是死板, 我們仍然叫c++是static language。??
?
????3. 希望更加靈活! 于是我們完全把上面哪個類的實現部分抽象出來,做成一套完整運行階段的檢測環境。這次再寫編譯器甚至保留部分代碼里的sytax名稱,名稱錯誤檢測,runtime環境注冊所以全局的類,函數,變量等等信息等等,我們可以無限的為這個層增加必要的功能。調用函數時候,會先從這個運行時環境里檢測所以可能的參數再做jmp跳轉。這,就是runtime。編譯器開發起來比上面更加彎彎繞。但是這個層極大增加了程序的靈活性。??例如當調用一個函數時候,前2種語言,很有可能一個jmp到了一個非法地址導致程序crash, 但是在這個層次里面,runtime就過濾掉了這些可能性。 這就是為什么dynamic langauge更加強壯。 因為編譯器和runtime環境開發人員已經幫你處理了這些問題。 ?
?
?
好了上面說著這么多,我們再返回來看objective-c.??現在你是不是能理解這樣的語句了呢??
?
復制代碼
  • id obj=self;
  • if ([obj respondsToSelector:@selector(function1:)) {
  • }
  • if ([obj isKindOfClass:[NSArray class]] ) {
  • }
  • ????????
  • if ([obj conformsToProtocol:@protocol(myProtocol)]) {
  • }
  • ????????
  • if ([[obj class] isSubclassOfClass:[NSArray class]]) {
  • }
  • [obj someNonExistFunction];
  • ?
    ?
    看似很簡單的語句,但是為了讓語言實現這個能力,語言開發者要付出很多努力實現runtime環境。這里運行時環境處理了弱類型、函數存在檢查工作。runtime會檢測注冊列表里是否存在對應的函數,類型是否正確,最后確定下來正確的函數地址,再進行保存寄存器狀態,壓棧,函數調用等等實際的操作。?
    ?
    復制代碼
  • id knife=[Knife grateKnife];
  • NSArray *monsterList=[NSArray array];
  • [monsterList makeObjectsPerformSelector:@selector(killMonster:) withObject:knife];
  • ?
    ?
    用c,c++完成這個功能還是比較非常麻煩的,但是動態語言處理卻非常簡單并且這些語句讓objc語言更加intuitive。?
    ?
    現在說一下runtime的負面影響:?
    1. 關于執行效率問題。 “靜態語言執行效率要比動態語言高”,這句沒錯。因為一部分cpu計算損耗在了runtime過程中。而靜態語言生成的機器指令更簡潔。正因為知道這個原因,所以開發語言的人付出很大一部分努力為了保持runtime小巧上。所以objecitve-c是c的超集+一個小巧的runtime環境。 但是,換句話說,從算法角度考慮,這點復雜度不算差別的,Big O notation結果不會有差別。( It’s not log(n) vs n2 )?
    2. 另外一個就是安全性。動態語言由于運行時環境的需求,會保留一些源碼級別的程序結構。這樣就給破解帶來的方便之門。一個現成的說明就是,java,大家都知道java運行在jre上面。這就是典型的runtime例子。它的執行文件.class全部可以反編譯回近似源代碼。所以這里的額外提示就是如果你需要寫和安全有關的代碼,離objc遠點,直接用c去。?
    ?
    簡單理解:“Runtime is everything between your each function call.”?
    ?
    但是大家要明白,第二點我提到runtime并不只是因為它帶來了這些簡便的語言特性。而是這些簡單的語言特性,在實際運用中需要你從完全不同的角度考慮和解決問題。只是計算1+1,很多語言都是一樣的,但是隨著問題的復雜,項目的增長,靜態語言和動態語言就會演化出完全不同的風景。?
    ?
    3. thread?
    ?
    "thread synchronization another notorious trouble!"??
    ?
    記不記得上學時候學得操作系統這門課,里面都會有專門一章介紹任務調度和生產者消費者的問題。 這就是為了今后使用進程、線程開發打基礎。概念很簡單,但是心知肚明的人很少。難點在synchronization(同步),因為1. There is no 100% deadlock detection algorithm. If there is, no deadlock at all. 2. 往往這類錯誤很隱晦,靜態分析很難找到。 3. 抽象度較高需要經驗去把握。???
    ?
    總體來說,我見到的在這方面的問題可以分為一下幾點:?
    ???
    1. 不知道多線程開發的幾個基點,看別人代碼越看越糊涂的。一會NSThread、一會Grand Central Dispatch、block等等。。。Apple封裝了很多線程的api, down to core多線程的結構基本是:?
    ?

    ??
    ?
    可以看到在多線程開發中你可以選擇這上面這4種不同的方式。?
    ?
    Mach是核心的操作系統部分。其實這個我也不是非常熟悉,至少我還沒有讀到過直接使用mach做多線程的代碼。?
    ?
    pthread(POSIX Threads)是傳統的多線程標準,靈活、輕巧,但是需要理論基礎,開發復雜。需要注意一點,根據apple文檔提示,在Cocoa下使用pthread需要先啟動至少一個NSThread,確定進入多線程環境后才可以。?
    ?
    NSThread是Mac OS 10.0后發布的多線程API較為高層,但是缺乏靈活性,而且和pthread相比效率低下。?
    ?
    Grand Central Dispatch 是10.6后引入的開源多線程庫,它介于pthread和NSThread之間。比NSThread更靈活、小巧,并且不需要像pthread一樣考慮很多lock的問題。同時objective-c 2.0發布的新語法特性之一blocks,也正是根據Grand Central Dispatch需求推出的。?
    ?
    所以在你寫多線程代碼或者閱讀多線程代碼時候,心理要先明確使用哪種技術。?
    ?
    ??? 2. thread和Reference Counting內存管理造成的問題。?
    ??線程里面的方法都要放到NSAutoreleasePool里面嗎這類問題很常見,主要原因是 NSAutoreleasePool 到底是干什么用得不明白。 NSAutoreleasePool跟thread其實關系并不顯著,它提供一個臨時內存管理空間,好比一個沙箱,確保不會有不當的內存分配泄露出來,在這個空間內新分配的對象要向這個pool做一下注冊告訴:“pool,我新分配一塊空間了”。當pool drain掉或者release,它里面分配過的內存同樣釋放掉??梢姾蛅hread沒有很大關系。但是,我們閱讀代碼的時候經常會看到,新開線程的函數內總是以NSAutoreleasePool開始結束。這又是為什么呢!? 因為thread內恰好是最適合需要它的地方! 線程函數應該計算量大,時間長(supposed to be heavy)。在線程里面可能會有大量對象生成,這時使用autoreleasepool管理更簡潔。所以這里的答案是,不一定非要在線程里放NSAutoreleasePool,相對的在cocoa環境下任意地方都可以使用NSAutoreleasePool。如果你在線程內不使用NSAutoreleasePool,要記得在內部alloc和relase配對出現保證沒有內存泄露。?
    ?
    ????3. 線程安全?
    ???每個程序都有一個主線程(main thread),它負責處理事件相應,和UI更新。?
    ?
    更新UI問題。很多新手會因為這個問題,導致程序崩潰或出現各種問題。而且逛論壇會看到所以人都會這么告訴你:“不要在后臺線程更新你的UI”。其實這個說法不嚴密,在多線程環境里處理這個問題需要謹慎,而且要了解線程安全特性。?
    ?
    首先我們需要把“UI更新”這個詞做一個說明,它可以有2個層次理解,首先是繪制,其次是顯示。這里繪制是可以在任何線程里進行,但是要向屏幕顯示出來就需要在主線程操作了。我舉個例子說明一下,例如現在我們有一個NSImageView,里面設置了一個NSImage, 這時我想給NSImage加個變色濾鏡,這個過程就可以理解為繪制。那么我完全可以再另外一個線程做這個比較費時的操作,濾鏡增加完畢再通知NSImageView顯示一下。另一個例子就是,Twitter客戶端會把每一條微博顯示成一個cell,但是速度很快,這就是因為它先對cell做了offscreen的渲染,然后再拿出來顯示。?
    ?
    所以通過這點我們也可以得到進一步的認識,合理設計view的更新是非常重要的部分。很多新手寫得代碼片段沒錯,只是因為放錯了地方就導致整個程序出現各種問題。?
    ?
    根據蘋果線程安全摘要說明,再其它線程更新view需要使用lockFocusIfCanDraw和unlockFocus鎖定,確保不會出現安全問題。?
    ?
    另外還要知道常用容器的線程安全情況。immutable的容器是線程安全的,而mutable容器則不是。例如NSArray和NSMutableArray。?
    ?
    ?????
    ????5. Asynchronous(異步) vs. Synchronous(同步)?
    ???? 引用 我在一個view要顯示多張web圖片,我想問一下,我是應該采用異步一個一個下載的方式,還是應該采用多線程同時下載的方式,還是2個都用,那種方式好呢? ?
    ?
    實際上單獨用這2個方法都不好。并不是簡單的用了更多線程就提高速度。這個問題同時涉及客戶端和服務器的情況。?
    ?
    處理這種類型的程序,比較好的結構應該是:非主線程建立一個隊列(相當于Asynchronous任務),隊列里同時啟動n個下載任務(相當于Synchronous任務)。這里的n在2~8左右就夠了。這個結構下可以認為隊列里面每n個任務之間是異步關系,但是這n個任務之間又是同步關系,每次同時下載2~8張圖片。這樣處理基本可以滿足速度要求和各類服務器限制。?
    ???
    (非常抱歉,之前質疑問問題的人理解錯誤。其實是我自己暈了,問得問題很好。)?
    ?
    4. runloop?
    現在說說runloop為何會成為cocoa開發中迷惑的點。因為很多新手沒有從動態角度看它。 首先回想一下第2點介紹的runtime的概念。 接著我出一個題思考一下。?
    ?
    現在我有一個程序片段如下:?
    復制代碼
  • - (void)myThread:(id)sender
  • {
  • ????NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
  • ????while (TRUE) {
  • ????????
  • ????????//do some jobs
  • ?????? //break in some condition
  • ????????
  • ????????usleep(10000);
  • ????????
  • ????????[pool drain];
  • ????}
  • ????
  • ????[pool release];
  • }
  • ?
    現在要求,做某些設計,使得當這個線程運行的同時,還可以從其它線程里往它里面隨意增加或去掉不同的計算任務。 這,就是NSRunloop的最原始的開發初衷。讓一個線程的計算任務更加靈活。 這個功能在c, c++里也許可以做到但是非常難,最主要的是因為語言能力的限制,以前的程序員很少這么去思考。?
    ?
    好,現在我們對上面代碼做一個非常簡單的進化:?
    ?
    復制代碼
  • NSMutableArray *targetQueue;
  • NSMutableArray *actionQueue;
  • - (void)myThread:(id)sender
  • {
  • ????NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
  • ????while (TRUE) {
  • ????????
  • ????????//do some jobs
  • ????????//break in some condition
  • ????????int n=[targetQueue count];
  • ????????assert(n==[actionQueue count]);
  • ????????for(int i=0;i<n;i++){
  • ????????????id target=[targetQueue objectAtIndex:i];
  • ????????????SEL action=NSSelectorFromString([actionQueue objectAtIndex:i]);
  • ????????????if ([target respondsToSelector:action]) {
  • ????????????????[target performSelector:action withObject:nil];
  • ????????????}
  • ????????}
  • ????????????????
  • ????????usleep(10000);
  • ????????
  • ????????[pool drain];
  • ????}
  • ????
  • ????[pool release];
  • }
  • ?
    注意,這里沒有做線程安全處理,記住Mutable container is not thread safe.?
    這個簡單的擴展,讓我們看到了如何利用runtime能力讓線程靈活起來。當我們從另外線程向targetQueue和actionQueue同時加入對象和方法時候,這個線程函數就有了執行一個額外代碼的能力。?
    ?
    但,有人會問,哪里有runloop? 那個是 nsrunloop? 看不出來啊。?
    復制代碼
  • while (TRUE) {
  • //break in some condition
  • }
  • ?
    一個線程內這個結構就叫線程的runloop,?? 它和NSRunloop這個類雖然名字很像,但完全不是一個東西。以前在使用靜態語言開始時候,程序員沒有什么迷惑,因為沒有NSRunloop這個東西。 我接著來說,這個NSRunloop是如何來得。?
    ?
    第二段擴展代碼里面確實沒有NSRunloop這個玩意兒,我們接著做第3次改進。 這次我們的目的是把其中動態部分抽象出來。?
    ?
    復制代碼
  • @interface MyNSTimer : NSObject
  • {
  • ??id target;
  • ??SEL action;
  • ??float interval;
  • ??CFAbsoluteTime lasttime;
  • }
  • - (void)invoke;
  • @end
  • @implementation MyNSTimer
  • - (void)invoke;
  • {
  • ??if ([target respondsToSelector:action]) {
  • ????????[target performSelector:action withObject:nil];
  • ????}
  • }
  • @end
  • ?
    ?
    ?
    復制代碼
  • @interface MyNSRunloop : NSObject
  • {
  • ??NSMutableArray *timerQueue;
  • }
  • - (void)addTimer:(MyNSTimer*)t;
  • - (void)executeOnce;
  • @end
  • @implementation MyNSRunloop
  • - (void)addTimer:(MyNSTimer*)t;
  • {
  • ??@synchronized(timerQueue){
  • ??????[timerQueue addObject:t];
  • ????}
  • }
  • - (void)executeOnce;
  • {
  • ??CFAbsoluteTime currentTime=CFAbsoluteTimeGetCurrent();
  • ??@synchronized(timerQueue){
  • ??????for(MyNSTimer *t in timerQueue){
  • ??????????if(currentTime-t.lasttime>t.interval){
  • ??????????????t.lasttime=currentTime;
  • ??????????????????[t invoke];
  • ??????????}
  • ??????}
  • ??}
  • }
  • @end
  • ?
    ?
    復制代碼
  • @interface MyNSThread : NSObject
  • {
  • ??MyNSRunloop *runloop;
  • }
  • - (void)main:(id)sender;
  • @end
  • @implementation MyNSThread
  • - (void)main:(id)sender
  • {
  • ????NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
  • ????while (TRUE) {
  • ????????//do some jobs
  • ????????//break in some condition
  • ????????[runloop executeOnce];
  • ????????usleep(10000);
  • ????????[pool drain];
  • ????}
  • ????[pool release];
  • }
  • @end
  • ?
    ?
    走到這里,我們就算是基本把Runloop結構抽象出來了。例如我有一個MyNSThread實例,myThread1。我可以給這個實例的線程添加需要的任務,而myThread1內部的MyNSRunloop對象會管理好這些任務。?
    ?
    復制代碼
  • MyNSTimer *timer1=[MyNSTimer scheduledTimerWithTimeInterval:1
  • ?????????????????????????????????????????????????? target:obj1
  • ???????????????????????????????????????????????? selector:@selector(download1:)];
  • [myThread1.runloop addTimer:timer1];
  • MyNSTimer *timer2=[MyNSTimer scheduledTimerWithTimeInterval:2
  • ?????????????????????????????????????????????????? target:obj2
  • ???????????????????????????????????????????????? selector:@selector(download2:)];
  • [myThread1.runloop addTimer:timer2];
  • ?
    ?
    當你看懂了上面的代碼也許會感嘆,‘原來是這么回事啊!為什么把這么簡單的功能搞這么復雜呢?’ 其實就是這么回事,把Runloop抽象出來可以使得線程任務管理更加loose coupling,給設計模式提供更大的空間。這樣第三方開發者不需要過深入的涉及線程內部代碼而輕松管理線程任務。另外請注意,這里MyNSRunloop, MyNSTimer等類是我寫得一個模擬情況,真實的NSRunloop實現肯定不是這么簡單。這里只為了說明一個思想。這種思想貫穿整個cocoa framework從界面更新到event管理。?
    ?
    5. delegate, protocol?
    這個會列出來因為,我感覺問它的數量僅此于內存管理部分,它們用得很頻繁,并且它們是多鐘設計模式的重要組成部分。?
    ?
    ?
    6. event responder?

    ?
    ?
    使用過Xcode的開發者都知道Interface Builder這個開發組件,在Xcode4版本以后該組件已經和xcode整合到一起。它是蘋果軟件開發中非常重要的部分。ib為開發者減輕了很大一部分界面設計工作。但是其中有一個東西讓新接觸ib的開發者一頭霧水,那就是First Responder, 它是什么東西,為何它會有那么多Actions。這節我會詳細介紹如何理解Responder和Cocoa下的事件響應鏈。?
    ?
    First Responder在IB屬性為Placeholders,這意味著它屬于一個虛擬實例。就好比TextField里面的string placeholder一樣,只是臨時顯示一下。真正的first responder會被其它對象代替。實際上,任何派生自NSResponder類的對象都可以替代First Responder。而First Responder里面的所有Actions就是NSResponder提供的接口函數,當然你也可以定義自己的響應函數。?
    ?
    MacOS在系統內部會維護一個稱為“The Responder Chain”的鏈表。該列表內容為responder對象實例,它們會對各種系統事件做出響應。最上面的哪個對象就叫做first responder,它是最先接收到系統事件的對象。如果該對象不處理該事件,系統會將這個事件向下傳遞,直到找到響應事件的對象,我們可以理解為該事件被該這個對象截取了。?
    ?
    The Responder Chain基本結構如下圖所示:?

    ?
    ?
    ?
    在理解了上面的概念之后,我希望使用一個例子讓大家對responder有更加具體的認識。大家都知道NSTextField這個控件,它是最常見的控件之一。它最基本功能是顯示一個字符串,如果啟用可選,那么用戶可以選中文本,拷貝文本,如果開啟編輯選項,還可以運行用戶編輯文本,等等基本操作。?
    ?
    下面展示給大家的例子是創建一個我們自己創建的簡單textfield叫LXTextField。它不屬于NSTextField而是派生自NSView,具有功能顯示字符串,全選字符串,響應用戶cmd+c的拷貝操作,三個基本功能。注意NSView派生自NSResponder。?
    ?
    ?
    復制代碼
  • @interface LXTextField : NSView
  • {
  • ????NSString *stringValue;
  • ????BOOL selectAll;
  • }
  • @property(retain,nonatomic) NSString *stringValue;
  • @end
  • @implementation LXTextField
  • @synthesize stringValue;
  • - (void)awakeFromNib
  • {
  • ????selectAll = NO;
  • }
  • - (id)initWithFrame:(NSRect)frameRect
  • {
  • ????if( self = [super initWithFrame:frameRect] ){
  • ????????selectAll = NO;
  • ????}
  • ????return self;
  • }
  • - (BOOL)acceptsFirstResponder
  • {
  • ????return YES;
  • }
  • - (BOOL)becomeFirstResponder
  • {
  • ????return YES;
  • }
  • - (BOOL)resignFirstResponder
  • {
  • ????selectAll=NO;
  • ????[self setNeedsDisplay:YES];
  • ????return YES;
  • }
  • - (void)setStringValue:(NSString *)string{
  • ????stringValue = string;
  • ????[self setNeedsDisplay:YES];
  • }
  • - (void)drawRect:(NSRect)dirtyRect
  • {
  • ????if (selectAll) {
  • ????????NSRect r = NSZeroRect;
  • ????????r.size = [stringValue sizeWithAttributes:nil];
  • ????????[[NSColor selectedControlColor] set];
  • ????????NSRectFill(r);
  • ????}
  • ????[stringValue drawAtPoint:NSZeroPoint withAttributes:nil];
  • }
  • - (IBAction)selectAll:(id)sender;
  • {
  • ????selectAll=YES;
  • ????[self setNeedsDisplay:YES];
  • }
  • - (IBAction)copy:(id)sender;
  • {
  • ????NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
  • ????[pasteBoard declareTypes:[NSArray arrayWithObjects:NSStringPboardType, nil] owner:nil];
  • ????[pasteBoard setString:stringValue forType:NSStringPboardType];
  • }
  • - (void)mouseDown:(NSEvent *)theEvent
  • {
  • ????if ([theEvent clickCount]>=2) {
  • ????????selectAll=YES;
  • ????}
  • ????[self setNeedsDisplay:YES];
  • }
  • - (void)keyDown:(NSEvent *)theEvent
  • {
  • }
  • @end
  • ?
    ?
    運行實例,可以看到隨著LXTextField收到系統發送的becomeFirstResponder消息,LXTextField變成responder chain中的frist responder, 這時候可以理解為IB里的哪個First Responder虛擬實例被該LXTextField取代。這時候mainMenu上哪些菜單項,例如:全選(cmd+a), 拷貝(cmd+a)等事件都會最先發給當前這個LXTextField。一旦你的LXTextField實現了NSResponder的哪些默認函數,那么該對象就會截取系統事件。當然這些事件具體如何實現還是需要你自己寫代碼實現。例如這里的 - (IBAction)copy:(id)sender; 顯然我手動實現了textfield的copy能力。?
    ?
    注意上述代碼中我實現了一個空函數- (void)keyDown:(NSEvent *)theEvent 這意味著我們希望LXTextField截取鍵盤事件而不再傳遞給responder chain后續對象。當然,如果我們希望LXTextField響應特定鍵盤事件,而其他事件繼續傳給其他響應對象,我們可以編寫如下代碼。?
    ?
    復制代碼
  • - (void)keyDown:(NSEvent *)theEvent
  • {
  • ????if(condition){
  • ????????do something;
  • ????}else{
  • ????????[super keyDown:theEvent];
  • ????}
  • }
  • ?
    ?
    7. mem-ory management?
    這個也許是問得最多的問題了吧。所有這些問題往往來源于3個地方,1、不了解底層機制;2、沒有吃透規則; 3、不了解常用container的Reference Counting特性,或著說沒有下功夫去看對應文檔。?
    ?
    1. 底層機制?
    大家是否知道從舊時代的RC到ARC機制到底意味著什么呢? 為什么ARC從開發速度,到執行速度和穩定性都要優于rc??
    ?
    開發速度不言而喻,你少寫很多release代碼,甚至很少去操心這部分。?
    ?
    執行速度呢?這個還要從runtime說起,還記得我在第2點說得一句話么:“Runtime is everything between your each function call.”???
    ?
    RC是一個古老的內存管理哲學:? 誰分配誰釋放。?通過counting來確定一個資源有幾個使用者。道理很簡單,但是往往簡單的東西人卻會犯錯。從來沒有一個程序員可以充滿信心的說,我寫得代碼從來沒有過內存泄露。這樣來看,我們就更需要讓程序可以自己處理這個管理機制,這就需要把這個機制放到runtime里。?
    ?
    所以RC->ARC就是把內存管理部分從普通開發者的函數中移到了函數外的runtime中。因為runtime的開發原型簡單,邏輯層次更高,所以做這個開發和管理出錯的概率更小。實際上編譯器開發人員對這部分經過無數次測試,所以可以說用arc幾乎不會出錯。另外由于編譯的額外優化,使得這個部分比程序員自己寫得代碼要快速很多。而且對于一些通用的開發模式,例如autorelease對象,arc有更優秀的算法保證autoreleasepool里的對象更少。 ?
    ?
    所以RC->ARC就是把內存釋放語句從普通開發者的代碼中去掉,然后交給編譯器讓它在編譯階段自動增加該有的釋放語句。 因為是編譯器分析,所以出錯的概率更小。實際上編譯器開發人員對這部分經過無數次測試,所以可以說用arc幾乎不會出錯。另外由于交給編譯器處理,使得這個部分比程序員自己寫得代碼要快速很多。?
    ?
    ARC另一個特點就是,強制程序員遵守owner規則。例如, 舊時很多程序員開發,喜歡在需要用的時候臨時建立一個windowController,窗口關閉后controller自己release掉。但是這個思路在arc下面是行不通的。因為這種模式打破了owner規則(一個實例需要至少有1個擁有者)一個臨時建立的windowController如果沒有owner,那么它會在當前函數退出前就被arc釋放掉。有些程序員認為這是arc非常討厭的地方,當然也有一些程序員認為這樣更規范。?
    ?
    ?
    2. RC規則?
    首先說一下rc是什么,r-Reference參照,引用 c-counting計數, rc就是引用計數。俗話說就是記錄使用者的數量?!±绗F在我有一個房間空著,大家可以進去隨意使用,但是你進門前,需要給門口的計數牌子+1, 出門時候-1?!∵@時候這個門口的牌子就是該房間里的人數。一但這個牌子變為0我就可以把房間關閉。?
    ?
    這個規則可以讓NSObject決定是不是要釋放內存。當一個對象alloc時候,系統分配其一塊內存并且object自動計數retainCount=1 這時候每當[object retain]一次retainCount+1(這里雖然簡寫也是rc不過是巧合或者當時開發人員故意選的retain這個詞吧)每次[object release]時候retainCount-1 當retainCount==0時候object就真正把這快內存還給系統。?
    ?
    3. 常用container的Reference Counting特性?
    這個規則很簡單把。但是這塊確實讓新手最頭疼的地方。 問題出在,新手總想去驗證rc規則,又總是發現和自己的期望不符合。? ?
    無數次看到有人寫下如下句子?
    復制代碼
  • NSLog(@"%d",[object retainCount]);
  • ?
    ?
    復制代碼
  • while([object retainCount]>0){
  • ??????[object release];
  • }
  • ?
    ?
    當然了,我也做過類似的動作,那種希望一切盡在掌握中的心態。但是你會看到其他人告訴這么做完全沒有意義。rc does not work this way.?? 也許這樣的暴力釋放會起作用,但是retainCount并不是用來做這個的。每個數字意味著有其它對象引用該資源,這樣的暴力釋放很容易導致程序崩潰。這個數字也許并不是你心目中的哪個。因為你很難跟蹤到底哪些對象引用的該資源。你用代碼建立的資源不光只有你的代碼才會用到,你調用的各種Framework,Framework調用的Framework,都有可能改變這個資源的retainCount.??所以去驗證rc規則不是明智之舉。?
    ?
    你能做的就是理解規則,使用規則,讀文檔了解container的引用特性?;蛘吒纱嘁频絘rc上面,讓runtime環境處理這些問題。?
    ?
    引用 我有一個NSMutableArray里面保存了1000個NSString對象,我在release的時候需要循環釋放1000個string么?還是只需要release NSMutableArray。 ?
    ?
    就像上面提到的,如果你了解container的引用特性,這個問題自然就解決了?!癗SMutableArray在添加、插入objects時會做retain操作。” 通過這一句話就分析出,用戶不否需要幫助NSMutableArray釋放1000個string?;貞浬厦嫣岬降墓芾碚軐W,“誰分配誰釋放” 編寫NSMutableArray的程序員非常熟悉這個規則,NSMutableArray內部retain了,NSMutableArray自然要負責release。但是NSMutableArray才不會管你在外面什么地方引用了這1000個string,它只管理好內部的rc就夠了。所以如果你在NSMutableArray外面對1000個string retain了,你自然需要release。相應的,你作為創建這個NSMutableArray的程序員,你只管release這個NSMutableArray就可以了。?
    ?
    最后說一下不用arc的情況。目前情況來看,有不少第三方的庫并未支持arc,所以如果你的舊項目使用了這些庫,請檢查是否作者發布了新版本,或者你需要自己修正支持arc。?
    ?
    8. class heritage and category?
    ?
    在這節里說明2個比較重要的問題,第一是subclass和category的區別。第二是新手最容易忽略的學習步驟。?
    ?
    Objective-C的Object-oriented programming特性提供subclass和category這2個比較非常重要的部分。subclass應該反復被各種編程書籍介紹過。它是oop繼承特性的關鍵語法,它給類添加了延續并且多樣化自己的方法。可以說沒有繼承就沒有oop這玩意。而category相對于subclass就不那么出名了。其實category思想出世于smalltalk,所以它不能算是一個新生事物。?
    ?
    先說一下這2個特性最主要的區別。簡單可以這么理解,subclass體現了類的上下級關系,而category是類間的平級關系。?
    ?

    ??
    ?
    如上圖所示,左側是subclass,可以看到class, subclass1, subclass2是遞進關系。同時下面的子類完全繼承父類的方法,并且可以覆蓋父類的方法。subclass2擁有function1,function2,function3三個函數方法。function1的執行代碼來自subclass1, function2的執行代碼來自于subclass2。?
    ?
    右側是category??梢钥吹?#xff0c;無論如何擴展類的category,最終就只有一個類class。category可以說是類的不同方法的小集合,它把一個類的方法劃分成不同的區塊。請注意觀察,每個category塊內的方法名稱都沒有重復的。這正是category的重要要求。?
    ?
    經過上面簡單解釋了解了這2點的基本區別,現在深入說一下category。?
    ?
    在Objective-c語言設計之初一個主要的哲學觀點就是盡量讓一個程序員維護龐大的代碼集。(對于龐大的項目‘原則’和‘協議’是非常重要的東西。甚至編寫良好的文件名都是非常重要的開發技巧)根據結構化程序設計的經驗出發,把一個大塊代碼劃分成一些小塊的代碼更便于程序員管理。于是objc借用了smalltalk的categories概念。允許程序員把一系列功能相近的方法組織到一個單獨的文件內,使得這些代碼更容易識別。?
    ?
    更進一步的,和c,c++這種靜態語言相比。objc把class categories功能集成到了run-time里面。因此,objc的categories允許程序員為已經存在的類添加新的方法而不需要重新編譯舊的類。一旦一個category加入,它可以訪問該類所有方法和實例變量,包括私有變量。?
    ?
    category不僅可以為原有class添加方法,而且如果category方法與類內某個方法具有同樣的method signature,那么category里的方法將會替換類的原有方法。這是category的替換特性。利用這個特性,category還可以用來修復一些bugs。例如已經發布的Framework出現漏洞,如果不便于重新發布新版本,可以使用category替換特性修復漏洞。另外,由于category有run-time級別的集成度,所以使得cocoa程序安全性有所下降。許多黑客就是利用這個特性(和posting技術2)劫持函數、破解軟件,或者為軟件增加新功能。一個很典型的例子就是,我發布的QQ表情管理器。?
    ?
    值得注意的一點是,由于一個類的categories之間是平級關系。所以如果不同categories擁有相同的方法,這個調用結果是未知的。所以:?
    ?
    引用 Category methods should not override existing methods (class or instance).??
    Two different categories implementing the same method results in undefined behavior?
    ?
    ?
    Objc中Categories有其局限的部分,就是你不能為原有的class添加變量,只能添加方法。當然方法里可以添加局部變量。在這個局限基礎上就有其它語言做了進一步改進,例如TOM語言就為Categories增加了添加類變量的能力。?
    ?
    總上所屬,如果你開發時候遇到無論如何都需要為類添加變量的情況,最好的選擇就是subclass。相反如果你只希望增加一些函數簇。Categories是最好的選擇。?
    ?
    并且我個人給大家的建議是,每個Cocoa程序員都應該收集整理自己的一套NS類函數的Categories擴展庫。這對你今后程序開發效率和掌控情況都有很大提高。?
    ?
    ?
    9. drawing Issues?
    ?
    大家都知道,MacOS是一個非常注重UI的系統。所以在MacOS編程里繪制是一個非常重要的部分。第10部分,我會從2點介紹MacOS下繪制編程。首先是繪制技術分類;其次是繪制代碼結構。?
    ?
    從繪制技術分類上看,Cocoa程序員能接觸的幾種繪制技術列表如下:?
    ?
    1. Cocoa Drawing(NS-prefix)?
    2. Core Graphics(CG-prefix, called Quazrtz 2D)?
    3. Core Animation?
    4. Core Image?
    5. OpenGL??
    ?
    在這里我不打算給大家介紹每一種都是如何繪制具體的圖像。只是介紹一下,它們大概長什么樣子,并且有什么優勢和限制。?
    ?
    ###Cocoa Drawing?
    Cocoa Drawing應該是學習Cocoa程序開發最先接觸的繪制技術。也是目前大多數MacOS程序所使用的繪制技術,其底層使用Quazrtz 2D(Core Graphics)。蘋果對應文檔為 [Cocoa Drawing Guide]( https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaDrawingGuide/Introduction/Introduction.html)。Cocoa Drawing并沒有統一的繪制函數,所有繪制函數分散在幾個主要的NS類的下面。例如, NSImage, NSBezierPath, NSString, NSAttributedString, NSColor, NSShadow,NSGradient …?
    ?
    所以很簡單,當你看到如下代碼就可以判斷,使用的是Cocoa Drawing方法?
    ?
    復制代碼
  • [anImage drawInRect:rect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
  • [@"some text" drawAtPoint:NSZeroPoint withAttributes:attrs];
  • NSBezierPath *p=[NSBezierPath bezierPathWithRect:rect];
  • [[NSColor redColor] set];
  • [p fill];
  • ?
    ?
    這種代碼多出現在NSView的drawRect函數內。Cocoa Drawing 的渲染上下文是 NSGraphicsContext,我不斷的看到很多新手把 NSGraphicsContext 和 CoreGraphics 的 CGContextRef 搞混。雖然它們很像并且也確實是有關系的,不過如果你不了解當繪制時候的 render context 很多時候將得到一個空白頁面的結果。?
    ?
    ###Core Graphics?
    Core Graphics 是 Cocoa Drawing layer 的底層技術,在 iOS 開發中非常普遍,因為 iOS 系統中并不存在 Cocoa layer 所以網上可以找到的多是 Core Graphics 繪制代碼段子,這給那些不了解 Mac 開發的新手來說造成了很大困擾。Cocoa 是 Mac OS 下的 application framework 而 iOS 下的 application framework 則是 UIKit.framework又叫 Cocoa Touch,它們分享部分代碼基礎但又不完全一樣。例如,Cocoa Touch 下的 UIView 的渲染上下文會使用 UIGraphicsGetCurrentContext() 取得,它得到的是一個 CGContextRef 指針,而在 NSView 里多用 [NSGraphicsContext currentContext] 取得渲染上下文。它得到的是一個 NSGraphicsContext 對象。當然 NSView 里也可以通過 CGContextRef ctx = [[NSGraphicsContext currentContext] graphicsPort]; 來取得一個 Core Graphics 渲染上下文。 可見 Mac OS 下的開發更為靈活一些。因為 iOS 中的 UIKit 開發初期就瞄準了顯卡硬件加速,所有 UIView 都是默認 layer-backed 的。iOS 開發者必須使用 Core Graphics 和 Core Animation 這幾個相對底層的繪制技術。?
    ?
    請看下面等價代碼,作用是繪制一個白色矩形。但是分別使用 Core Graphics 和 Cocoa Drawing:?
    ?
    復制代碼
  • const CGFloat white[]={ 1.0, 1.0, 1.0, 1.0 };
  • CGContextSetFillColor(cgContextRef, white);
  • CGContextSetBlendMode(cgContextRef, kCGBlendModeNormal);
  • CGContextFillRect(cgContextRef, CGRectMake(0, 0, width, height));
  • [[NSColor whiteColor] set];
  • NSRectFillUsingOperation(NSMakeRect(0, 0, width, height), NSCompositeSourceOver);
  • ?
    ?
    可以看出,這是2種*風格完全不同*的繪制技術。Cocoa Drawing 是分散式的繪制函數,而 Core Graphics 是傳統的類似 OpenGL 的集成式的繪制方式。其實 Cocoa Drawing 下層是 Core Graphics, Core Graphics 的下層是 OpenGL。?
    ?
    ?
    ###Core Animation?
    如果說 Core Graphics 和 Cocoa Drawing 是通用的 UI 繪制框架的話,那么 CA 顯然是界面動畫繪制的高級技術。?
    Core Animation 的對應 Cocoa Animation 部分應該是 NSAnimation 和 NSViewAnimation,但這2個差距比較大。NSAnimation 出現與 OS X 10.4,Core Animation 是 10.5 后出現的。NSViewAnimation 功能和使用相對簡單。?
    ?
    簡單來說,Core Animation 的作用對象是 CALayer, NSAnimation 的作用對象是 NSView。


    轉載于:https://my.oschina.net/u/1027869/blog/124398

    總結

    以上是生活随笔為你收集整理的迷惑新手的IOS开发问题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    中文字幕色在线 | 国产精品久久久一区二区 | 亚洲在线视频播放 | 国产精品一区二区62 | 日韩精品中文字幕在线 | 最新av中文字幕 | 免费黄a大片 | 日韩在线观看一区二区三区 | 国产亲近乱来精品 | 99热在线看 | 久久精品男人的天堂 | 久久爱www.| 婷婷深爱五月 | 国产在线无 | 四虎在线观看精品视频 | 国产精品理论视频 | 日韩久久午夜一级啪啪 | 欧美精品久久久久久久久老牛影院 | 日本狠狠干 | 五月婷婷视频在线观看 | 婷婷网站天天婷婷网站 | 久久99深爱久久99精品 | 狠狠色丁香久久婷婷综合五月 | 国产一二三四在线观看视频 | 热久久免费视频 | 五月精品 | 免费看成人| 亚洲精品免费在线播放 | 99久高清在线观看视频99精品热在线观看视频 | 国产黄色免费看 | 久久网页| 99视频在线| 毛片网在线观看 | 中文字幕电影在线 | 国产精品午夜久久久久久99热 | 99精彩视频在线观看免费 | 六月激情久久 | 黄色毛片视频免费观看中文 | 色吊丝在线永久观看最新版本 | 天天婷婷 | 国产91免费看 | 在线观看91精品国产网站 | 国色天香第二季 | 精品久久久免费视频 | 国产一区二区影院 | 毛片精品免费在线观看 | 成人a毛片 | 一区二区三区免费在线播放 | 久久99热国产 | 久久精品视频3 | 一区二区不卡 | 国产精品 999 | 天天av综合网| 一级成人网 | 国产精品久久久久久吹潮天美传媒 | 色悠悠久久综合 | 国产中文字幕视频在线观看 | 亚洲人成免费网站 | 日本夜夜草视频网站 | 超碰97成人| 日本99热 | 贫乳av女优大全 | 免费在线观看国产精品 | av免费网 | 999视频在线播放 | 91一区二区三区在线观看 | 成人91免费视频 | 狠狠操天天操 | 夜夜躁狠狠躁日日躁视频黑人 | 在线观看中文字幕一区二区 | 日本最新中文字幕 | 操碰av | 色婷婷综合久久久久中文字幕1 | 日韩手机在线观看 | 国产r级在线观看 | 国产在线探花 | 国产视频精品网 | 午夜精品一区二区三区四区 | 精品极品在线 | 西西4444www大胆无视频 | 国产亚洲精品久久久久动 | 四虎影视成人精品国库在线观看 | 69国产精品成人在线播放 | 黄色日本片 | 亚洲福利精品 | 狠狠黄| 亚洲精品综合欧美二区变态 | 女人高潮一级片 | 国产高清精 | 国产精品99久久免费观看 | 日韩在线视频观看 | 中文字幕日本在线观看 | 久久婷婷精品 | 一区二区三区电影大全 | 麻豆视频一区 | 国产精品成人一区二区三区吃奶 | 国产小视频免费观看 | 亚洲一区二区视频在线 | 成人在线视频网 | 最新高清无码专区 | 天天操天天操天天操天天操天天操天天操 | 国产精品99久久久久久久久 | 久久五月婷婷丁香社区 | 亚洲精品中文在线 | 夜夜操夜夜干 | 午夜色婷婷 | 久久久久99精品国产片 | 国产精品成人久久 | 91一区二区三区久久久久国产乱 | 在线看成人 | 一区二区三区不卡在线 | 中文字幕亚洲欧美日韩2019 | 天天干夜夜操视频 | 91看片在线播放 | 亚洲综合丁香 | 色综合激情久久 | 久久亚洲二区 | 插婷婷| 国产在线自 | 国产黄色片久久久 | 免费a v在线| 五月av在线 | 日韩精品不卡在线观看 | 97国产超碰在线 | 欧美成人高清 | 久久久久久久久久久影视 | 91在线精品视频 | 国产高清视频在线观看 | av不卡免费在线观看 | 99热在线国产精品 | 丁香六月天 | 欧美极品一区二区三区 | 日韩精品久久久免费观看夜色 | 欧美性生活一级片 | 成人午夜精品 | 国内精品二区 | 精品久久国产精品 | 久久婷婷国产色一区二区三区 | 国产精在线 | 国产免费人成xvideos视频 | 精品久久91| 日日弄天天弄美女bbbb | 182午夜在线观看 | 国产一级二级三级在线观看 | 一级免费片 | 视频在线观看入口黄最新永久免费国产 | 国产精品一区二区av日韩在线 | www五月天com | 色黄视频免费观看 | 国产精品一区二区久久精品爱微奶 | 最新av电影网站 | 五月天激情综合网 | 久久午夜影视 | 在线一区电影 | 91大神精品视频在线观看 | 国产免费又粗又猛又爽 | av电影在线播放 | 狠狠狠色丁香婷婷综合久久88 | 成人黄色小说在线观看 | 久久亚洲热 | av 在线观看 | 少妇按摩av | 亚洲精品免费观看视频 | 色综合久久久久综合体 | 免费看一及片 | 探花视频在线版播放免费观看 | 精品国产自在精品国产精野外直播 | 国产在线观看地址 | 久久www免费人成看片高清 | 精品人妖videos欧美人妖 | 精品国产乱码久久久久久天美 | 免费观看成人 | 久精品在线 | 27xxoo无遮挡动态视频 | 91漂亮少妇露脸在线播放 | 日日弄天天弄美女bbbb | 国产日韩欧美在线观看 | 国产精品麻 | 亚洲老妇xxxxxx | 在线免费国产 | 91麻豆免费版 | 婷婷丁香在线视频 | 欧美精品一区二区三区一线天视频 | 99精品国产99久久久久久福利 | 免费看片网页 | 福利一区在线视频 | 亚洲综合激情五月 | 狠狠干免费 | 91高清视频在线 | 久久国产女人 | www夜夜| 久久 在线| 一区二区三区手机在线观看 | 国产专区精品视频 | 亚洲精品456在线播放 | 久久免费播放 | 日本在线观看黄色 | 在线免费观看欧美日韩 | 国产精品18久久久久久久 | 日韩理论视频 | 亚洲涩涩涩涩涩涩 | 狠狠久久伊人 | 久久精品999 | 日本久久电影 | 国产精品国产三级国产aⅴ无密码 | 色欲综合视频天天天 | av观看在线观看 | 亚洲五月六月 | 日韩高清精品免费观看 | 四虎影视成人精品国库在线观看 | 亚洲国内精品在线 | 久久午夜国产精品 | 毛片精品免费在线观看 | 97国产精品免费 | av在线播放中文字幕 | 成人欧美一区二区三区黑人麻豆 | 国产成人黄色 | 91福利免费 | 日韩高清免费观看 | 国产美女精品视频免费观看 | 四虎影视成人精品国库在线观看 | 欧美另类sm图片 | 狠狠躁夜夜av| 天天操天天射天天操 | 日日干视频 | 人人玩人人添人人澡超碰 | 久久国色夜色精品国产 | 久久丁香网 | 81国产精品久久久久久久久久 | 成人黄色视| 久久国内精品视频 | 91精品日韩 | 精品免费久久久久久 | 国产视频97 | www亚洲一区| 国产黄免费在线观看 | 91麻豆操 | 天天色天天骑天天射 | 久久99影院 | 五月婷婷毛片 | 欧美精品一区二区三区一线天视频 | 九九色在线| 69精品在线 | 激情婷婷在线 | 少妇bbbb搡bbbb桶| 黄色一级影院 | 国产一级免费av | 国产亚洲人成网站在线观看 | 嫩草伊人久久精品少妇av | 国产精品一区二区62 | 国产97在线观看 | 香蕉视频国产在线观看 | 91在线最新 | 狠狠干天天操 | 六月丁香在线视频 | 91精品看片| 天天操天天干天天插 | 91av视频在线观看免费 | 天堂av在线中文在线 | 国产中文字幕视频在线观看 | 亚洲污视频 | 91新人在线观看 | 免费黄色激情视频 | 日本精品一区二区在线观看 | 国产中文字幕视频在线观看 | 丁香资源影视免费观看 | 97在线视频观看 | 日韩动漫免费观看高清完整版在线观看 | 国产成人精品电影久久久 | 黄色aaa毛片 | 一区二区三区精品在线 | 久草视频视频在线播放 | 亚洲精品456在线播放 | 久久久久久久久久久久国产精品 | 亚洲综合在线发布 | 亚洲精品黄色在线观看 | 91麻豆传媒 | 在线观看黄网 | 午夜成人免费影院 | 国产精品日韩高清 | 亚洲91网站 | 最近高清中文在线字幕在线观看 | 日韩免费av网址 | 国产精品一区二区吃奶在线观看 | 久久调教视频 | 香蕉视频网址 | 五月婷婷激情六月 | 免费看三级黄色片 | 中文字幕乱偷在线 | 天天插狠狠插 | 久草精品在线 | 亚洲国内精品 | 三级av免费 | 干干干操操操 | 亚洲综合激情小说 | av一本久道久久波多野结衣 | av先锋中文字幕 | 久草久草在线 | 天天激情站 | free. 性欧美.com | 久久免费视频播放 | 亚洲精品视频大全 | 国产一区二区视频在线 | 狠狠操精品 | 久久理论视频 | 国产亚洲精品久久久久久久久久久久 | 亚洲成人精品国产 | 午夜久久网站 | 亚洲一区二区黄色 | 久久高清毛片 | www天天干com| 久久tv视频 | 亚洲精品国产区 | 一区二区三区高清在线 | 黄视频网站大全 | 精品视频9999 | 激情综合网在线观看 | 婷婷丁香花 | 国产成人精品久久久久蜜臀 | 日韩av高潮 | 91精品一区二区三区久久久久久 | 一级黄色片在线 | 亚洲国产精品va在线看黑人动漫 | 国产精品久久久影视 | 国产字幕在线观看 | 波多野结衣视频网址 | 欧美成人理伦片 | 91视频麻豆视频 | 97人人视频 | 国产精品一区在线观看 | 黄色毛片在线观看 | 天天操天天操天天操天天操天天操 | 国产精品1区2区在线观看 | 四虎8848免费高清在线观看 | 国产中文字幕av | 亚洲精品久久久蜜桃直播 | 一区二区三区四区免费视频 | www.av在线播放 | 成 人 黄 色 免费播放 | 亚洲午夜久久久久久久久电影网 | 国产成人亚洲在线观看 | 精品超碰 | 国产精品不卡视频 | 超碰人人干人人 | 麻豆视频免费在线观看 | 久久久免费少妇 | 久久综合婷婷国产二区高清 | 91麻豆精品国产91久久久使用方法 | 欧美性精品 | 超碰在线97国产 | 黄网站app在线观看免费视频 | 在线播放 亚洲 | 日韩免费视频网站 | 人人干人人模 | 欧美一级片免费在线观看 | 久久开心激情 | 福利视频网站 | 亚洲视频网站在线观看 | 99久久国产免费看 | 亚洲最大色| 亚洲第一色 | 国产日本在线播放 | 久久亚洲免费 | av在线小说 | 国产精品一区二区免费在线观看 | 亚洲精品字幕 | 免费av黄色 | 六月丁香社区 | 亚洲精品国产高清 | 美女视频黄在线观看 | 国产国产人免费人成免费视频 | 久久久免费国产 | 国产精品99久久久精品免费观看 | 色偷偷88欧美精品久久久 | 久久a免费视频 | 成年人国产在线观看 | 四虎免费在线观看视频 | av电影不卡在线 | 激情av在线资源 | 黄色大片入口 | 久久精品毛片基地 | 182午夜在线观看 | 99久久精品一区二区成人 | 国产日本高清 | 国产流白浆高潮在线观看 | 日韩久久精品一区二区 | 国产超碰在线 | 国内精自线一二区永久 | 亚洲成a人片在线观看网站口工 | 黄色小说在线观看视频 | 91看片在线 | 玖玖在线免费视频 | 激情五月看片 | 欧美有色 | 亚洲欧美日本一区二区三区 | 久久超碰网 | 五月婷网站| 黄色大全免费观看 | 中文字幕电影在线 | 日韩免| 欧美日韩国产一区二 | 亚洲aⅴ在线| 狠狠狠的干 | 2021av在线 | 天海冀一区二区三区 | 久草网首页 | 国产精品99久久久久的智能播放 | 国产成人精品女人久久久 | 亚洲影院一区 | 国产一区二区在线免费视频 | 五月天开心 | 最近2019年日本中文免费字幕 | 精品久久1| 日韩美在线观看 | 精品美女久久久久久免费 | 精品在线二区 | 日韩a在线 | 日韩久久一区 | 97在线观看免费视频 | 国产一区二区综合 | 国产精品成人久久久久久久 | 嫩草av在线| 91av国产视频 | 亚洲精品五月天 | 国产精品久久久久久久久久东京 | 91最新在线| 国产亚洲精品久久 | av在线免费不卡 | 欧美韩国日本在线观看 | 欧美一级片免费播放 | 国产毛片久久 | 99热精品在线观看 | 99视频国产精品免费观看 | av成人免费| 免费h漫在线观看 | 国产98色在线 | 日韩 | 91麻豆看国产在线紧急地址 | 免费黄色av | 成人激情开心网 | 久久精品一区二 | 日韩中文字幕a | 国产一二三四在线视频 | 日韩在线三区 | 啪啪免费观看网站 | 国产99久久九九精品 | 又色又爽又黄 | 亚洲精品资源在线观看 | 亚洲午夜久久久综合37日本 | 国偷自产中文字幕亚洲手机在线 | 91av原创 | 91伊人影院| 美女视频黄的免费的 | 国产美女免费观看 | 亚洲精品在线免费 | 日韩精品高清不卡 | 天堂v中文 | 伊人网综合在线观看 | 最新av在线播放 | 国产精品一区二区久久 | 国产免费三级在线观看 | 91精品久久久久久久久久入口 | 国产精品一区二区三区电影 | 丁香在线视频 | 免费av网址大全 | 91精品久久久久久粉嫩 | 99免费国产 | 天天干天天搞天天射 | 久久精彩免费视频 | 91xav| 国产综合精品一区二区三区 | 国产高清中文字幕 | 日韩欧美大片免费观看 | 一级片视频免费观看 | 成人免费看黄 | 91视频-88av| 中文在线字幕免 | 免费在线观看不卡av | 国产精品女同一区二区三区久久夜 | 国产亚洲永久域名 | 蜜臀av性久久久久蜜臀av | 天天艹天天干天天 | 国产精品久久久久久久久搜平片 | 一区二区三区四区影院 | 国产视频一区精品 | 国产精品18videosex性欧美 | 免费亚洲黄色 | 黄污污网站| 黄色h在线观看 | 久久久久国产精品免费免费搜索 | 99热在线观看免费 | 亚洲视频免费在线观看 | 久久91久久久久麻豆精品 | 亚洲婷婷在线视频 | 96精品视频 | 亚洲欧美日本国产 | 中文字幕免费在线看 | 久一网站 | 欧美日韩不卡一区二区三区 | 久久精品91久久久久久再现 | 黄色一级动作片 | 久久国产精品久久精品国产演员表 | 久久情侣偷拍 | 久久婷婷综合激情 | 91爱爱中文字幕 | 二区三区在线视频 | 国产精品18久久久久久首页狼 | 国产精品日韩欧美 | 国产亚洲欧美日韩高清 | 国产一区免费在线观看 | 区一区二在线 | 久久8 | 丁香婷婷色综合亚洲电影 | 香蕉国产91 | 国产精品黑丝在线观看 | 色播六月天| 97视频免费在线 | 一区二区精品在线 | 国产亚洲欧美在线视频 | 久久国产精品久久国产精品 | 久久九九久久精品 | 久久综合9988久久爱 | 免费看片成年人 | 干狠狠| 91亚洲在线观看 | 91大神在线观看视频 | 国语久久 | 精品欧美一区二区在线观看 | 免费a v在线| 亚洲一级黄色 | 精品999在线观看 | 国产日韩精品视频 | 五月婷婷在线播放 | 黄色国产在线 | 色爱区综合激月婷婷 | av中文在线播放 | 97成人在线观看视频 | 日本中文在线观看 | 日韩av在线一区二区 | 婷婷中文在线 | 一区二区三区免费在线观看视频 | 国产专区一 | 色噜噜在线观看 | av成人免费在线观看 | 成人免费观看在线视频 | 亚洲五月激情 | 国产精品人人做人人爽人人添 | 五月天婷婷在线观看视频 | 久久99精品久久久久蜜臀 | 天堂av色婷婷一区二区三区 | 三级午夜片 | 免费久久精品视频 | 亚洲精品视频网 | 日韩大片在线免费观看 | 99久久久久久久久 | 久久视屏网 | 国产五十路毛片 | av怡红院| 久久精品www人人爽人人 | 免费视频成人 | 国内小视频在线观看 | 日韩中文字幕视频在线 | 国产在线观看黄 | 最近2019好看的中文字幕免费 | 日韩一区二区三区高清在线观看 | 日韩精品亚洲专区在线观看 | 免费精品视频在线观看 | 夜夜躁狠狠燥 | 69av免费视频| 国产丝袜在线 | 黄色成人在线观看 | 久久激五月天综合精品 | 狠狠干天天 | 亚洲精品美女久久17c | 在线观看电影av | 黄色网址在线播放 | 99在线看 | 色婷av| 精品日本视频 | 深夜视频久久 | 久久伦理视频 | 国产小视频网站 | 超碰免费观看 | 久久久综合香蕉尹人综合网 | 久久久久久久久久久久电影 | 夜夜操天天干 | 成人av电影免费在线观看 | 久久在线免费 | 黄色免费大片 | 亚洲免费在线播放视频 | 99在线视频精品 | 久久精品网址 | 久久天天躁夜夜躁狠狠躁2022 | 91超级碰碰| 国产高清小视频 | 亚洲激情一区二区三区 | 中文字幕第| 国产视频一二三 | 免费v片 | 天天干天天爽 | 国产第一福利 | 免费在线一区二区 | 欧美日韩高清在线观看 | 狠狠干狠狠操 | 六月丁香社区 | 日韩在线观看电影 | 特级西西444www高清大视频 | 亚洲精品在线观 | 久草9视频 | 精品特级毛片 | 欧美福利片在线观看 | 欧美一区二区三区免费观看 | 欧美专区日韩专区 | 五月天堂网 | 亚洲欧美日韩在线看 | 久久一精品 | 国产成人精品久 | 国产成人333kkk | 日韩理论在线视频 | 99热精品久久 | 在线免费黄 | 精品久久久久一区二区国产 | 久久黄色免费观看 | avsex| 天天插天天干 | 国产亚洲精品久久久久久网站 | 久久综合免费视频 | 午夜精品久久久久久久爽 | 麻豆视频成人 | 国产一区二区三区免费观看视频 | 欧美视频日韩 | 国产一区二区三区免费在线观看 | 五月天开心 | 午夜免费电影院 | 国产精品99页| 国产成人一区二区精品非洲 | 久久久国产影院 | av不卡免费在线观看 | 精品国产精品国产偷麻豆 | 精品亚洲欧美无人区乱码 | 播五月综合 | 欧美另类交在线观看 | 亚洲精品午夜国产va久久成人 | 国产伦精品一区二区三区高清 | 激情婷婷| 国产999精品久久久久久 | 制服丝袜一区二区 | 色大片免费看 | 99热精品国产一区二区在线观看 | 久久精品国产v日韩v亚洲 | 欧洲精品视频一区二区 | 日韩av视屏 | 亚洲精品mv在线观看 | 国产精品视频最多的网站 | 黄色午夜网站 | 国产成人精品免费在线观看 | av大全在线免费观看 | 91色蜜桃 | 久久久视屏| 国产成人精品av久久 | 999视频网站 | 免费看片网页 | 高清不卡一区二区在线 | 亚洲在线视频播放 | 国产精品免费视频久久久 | 九九九九热精品免费视频点播观看 | 国产日本高清 | 国产在线污 | 久久久久久麻豆 | 在线直播av | 在线视频18在线视频4k | 亚洲国产精品久久久久 | 欧美一级性视频 | 免费婷婷| 在线观看av黄色 | 天天伊人狠狠 | 一区二区三区免费在线播放 | 99久热在线精品视频成人一区 | 成人av免费在线看 | 99热这里只有精品免费 | 国产成人福利在线观看 | 少妇bbbb | 国产免费不卡av | 在线观看av中文字幕 | 国产精品久久久久久久久婷婷 | 国产手机av在线 | 婷婷激情五月 | 91久久影院 | 精品成人a区在线观看 | 亚洲美女视频网 | 五月天六月色 | 综合伊人av | 婷婷九九| 日韩电影中文,亚洲精品乱码 | 国产成人精品一区一区一区 | 日韩av成人在线观看 | 国产精品久久久久久久久久不蜜月 | 91精品一区国产高清在线gif | 日韩成人看片 | bbb搡bbb爽爽爽 | 欧美日韩免费观看一区=区三区 | www.操.com | 久久免费大片 | 国产一区精品在线 | 高清不卡毛片 | 男女拍拍免费视频 | 精品91在线 | 91精品在线免费观看视频 | 日韩欧美精品在线观看视频 | 精品久久久久久久久久久久久久久久久久 | 成人在线视频在线观看 | 国产黄色片在线免费观看 | 黄色片视频在线观看 | 99国产一区 | 久久不卡免费视频 | 99精品一区二区三区 | 成人av电影免费在线播放 | 精品国产日本 | 天天干天天玩天天操 | 综合天天 | 天天操天天干天天操天天干 | 久久欧美综合 | 国产 视频 高清 免费 | 色www.| 国产精品久久久久影院 | 在线a亚洲视频播放在线观看 | 国产成人久久av免费高清密臂 | 免费在线观看日韩欧美 | 色综合久久久久久中文网 | 四虎国产永久在线精品 | 日韩一区二区三区在线看 | 黄色国产大片 | 91成熟丰满女人少妇 | 亚洲精品在线一区二区 | 天天干天天干天天干天天干天天干天天干 | 国产精品午夜8888 | 国产精品久久99综合免费观看尤物 | av午夜电影 | 最新成人av | 成 人 黄 色 片 在线播放 | 亚洲精品视频二区 | 久草在线视频新 | 成人在线观看日韩 | 中文字幕欧美三区 | 久久精品视频在线观看 | 日韩综合视频在线观看 | 国产亚洲精品久久久久久久久久久久 | 中文字幕av在线免费 | 免费在线国产黄色 | 91免费看片黄 | 久久a视频 | 91av视频观看 | 亚洲天堂网视频在线观看 | www.色在线| 免费久久99精品国产婷婷六月 | 欧美激情亚洲综合 | 中文字幕在线看人 | 人人爽人人干 | 久久国产精品视频 | 久久国产高清 | 国产精品综合av一区二区国产馆 | 久久国产欧美日韩精品 | 中文视频一区二区 | 一级做a爱片性色毛片www | 国内精品久久久久久久久 | 欧美a影视 | 日韩在线二区 | 日本女人逼 | av大全在线观看 | 91精品久久久久久综合乱菊 | 国产在线91在线电影 | 91av蜜桃| 久久久久综合精品福利啪啪 | av 一区二区三区 | 久久国产精品99久久人人澡 | 久久久www免费电影网 | 黄色免费大全 | 三级动态视频在线观看 | 在线观看亚洲专区 | 美女福利视频 | 黄色网www| 九九热精品视频在线播放 | 欧美日本在线观看视频 | 午夜黄色一级片 | 四虎影视国产精品免费久久 | 亚洲a成人v | 狠狠狠色丁香婷婷综合久久88 | 国产日韩av在线 | 成人免费 在线播放 | 综合色中文 | 日本一区二区三区视频在线播放 | 久久大视频 | 午夜 在线 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 成全在线视频免费观看 | 91av蜜桃| 国产高清在线免费视频 | 久久久精品国产一区二区三区 | 精品伊人久久久 | 国产精品毛片一区视频 | 丁香婷婷激情网 | 亚洲精品国产精品国 | 久久久一本精品99久久精品66 | 国产传媒中文字幕 | 亚洲久草在线 | 国产精品欧美久久久久天天影视 | 久久久久久久99精品免费观看 | 成人免费亚洲 | 色香天天 | 美女视频永久黄网站免费观看国产 | 国内精品久久久久影院男同志 | 国产超碰97 | 人人讲下载 | 亚洲精品玖玖玖av在线看 | 91久久黄色| 欧美日韩国产精品久久 | 在线国产欧美 | 婷婷丁香花 | 日韩一二三区不卡 | 午夜av在线电影 | 久爱精品在线 | 免费av影视 | 久久精品美女视频 | 91成人网页版 | 国产色黄网站 | 视频精品一区二区三区 | 日韩影视大全 | 国产精品免费久久久久影院仙踪林 | 日韩欧美精品一区 | 日韩欧美黄色网址 | 中文永久免费观看 | 免费观看9x视频网站在线观看 | 黄色小说免费观看 | 国产一区免费 | av电影免费观看 | 狠狠干婷婷色 | 一区二区欧美在线观看 | sesese图片 | 亚洲国产小视频在线观看 | 黄色精品久久 | 豆豆色资源网xfplay | 亚洲成人高清在线 | 懂色av一区二区三区蜜臀 | 国产精品久久久久久久免费大片 | 精品久久久影院 | 国产一级二级在线 | 国产一级黄色av | 黄色成人av网址 | 日韩女同一区二区三区在线观看 | 97超碰中文字幕 | 免费福利视频导航 | av电影在线不卡 | 午夜12点 | 一级精品视频在线观看宜春院 | 99热这里精品 | 免费在线色 | 婷婷在线网 | av网在线观看 | 成人在线视频免费看 | 亚洲综合欧美日韩狠狠色 | 国产精品永久免费在线 | 久久成人一区 | a色视频 | 日韩午夜视频在线观看 | 91色综合| 日韩伦理片hd | 日韩影视在线观看 | 色婷婷综合久久久久 | 国产视频久久 | 久久综合色婷婷 | 国产精品毛片久久 | 欧美久草视频 | 99欧美视频| 9在线观看免费高清完整版在线观看明 | 午夜电影一区 | 午夜精品视频在线 | 欧美日韩aa| 久久激情网站 | 园产精品久久久久久久7电影 | 亚洲一级免费电影 | 精品一区精品二区高清 | 国产精品6 | 国产在线播放一区二区三区 | av在线h| 国产福利午夜 | 亚洲欧洲av在线 | 91麻豆免费版 | 天天干天天射天天爽 | 亚洲精品美女久久久久网站 | 久热电影| 麻豆影视在线观看 | 国产偷国产偷亚洲清高 | 久久九九国产精品 | 香蕉影院在线 | 亚洲精品视频网站在线观看 | 精品免费观看 | 色播99 | 久久久国产精品人人片99精片欧美一 | 亚洲最大av网站 | 天天操夜夜逼 | 99中文字幕 | 成年人免费在线观看 | 亚洲欧美国产精品va在线观看 | 成 人 黄 色 片 在线播放 | 精品国产一区二区三区蜜臀 | 99一区二区三区 | 天天操天天干天天爱 | 麻豆视频免费播放 | 一级黄色片在线 | 黄色一级性片 | 一区二区观看 | 欧美一区二区日韩一区二区 | 免费在线观看av网址 | 国产免费高清 | 国产一区二区三区高清播放 | 中文字幕免费观看视频 | 超碰97免费 | 国产视频导航 | 色噜噜日韩精品欧美一区二区 | 一级黄色免费 | 久草网视频 | 97在线观看免费观看高清 | 久久久亚洲网站 | 国产一级免费观看视频 | 黄色av电影在线观看 | 男女啪啪视屏 | 国产一区二区久久精品 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 毛片一级免费一级 | 国产精品久久久久久久久久99 | 91精品国自产在线 | a天堂一码二码专区 | 国产中文字幕91 | 91人人网 | 黄网站大全| 天天操夜夜想 | 亚州欧美视频 | 在线黄色免费av | 夜夜高潮夜夜爽国产伦精品 | 免费在线一区二区 | 免费午夜网站 | 成人黄色大片 | 日韩精品五月天 | 国内精品视频一区二区三区八戒 | 日韩在线视频国产 | 91麻豆精品国产91久久久无限制版 | 美女黄频视频大全 | 日韩欧美电影网 | 国内精品美女在线观看 | 欧洲成人av | 久久最新 | www.啪啪.com| 欧美激情视频久久 | 91在线免费视频观看 | 日产乱码一二三区别在线 | 一区二区三区在线免费观看 | 高潮毛片无遮挡高清免费 | 天天干 夜夜操 | 五月天久久婷 | 成年人免费在线 | 黄色资源在线观看 | 久久不卡国产精品一区二区 | 成人黄色大片在线观看 | 国产在线精品区 | 免费在线播放视频 | 国产精品精品久久久久久 | 黄色大片日本免费大片 | 丁香六月网 | 中文字幕高清免费日韩视频在线 | 日韩欧美一区视频 | 99精品国产兔费观看久久99 | 天天干,天天干 | 欧美一级片在线播放 | www.久艹| 国产理论一区二区三区 | 在线免费国产 | 黄色电影在线免费观看 | 在线观看黄污 | 日韩精品中文字幕久久臀 | 国产精品国产毛片 | 日本动漫做毛片一区二区 | 能在线看的av | 精品美女在线视频 | 国产视频在线播放 | 国产成人一区二区三区在线观看 | 国产成人福利在线观看 | 亚洲国产精品小视频 | 亚洲国产中文在线观看 | 激情综合久久 | 久久97精品 | 亚洲色图色| 精品婷婷 | 夜夜干天天操 | 国产一区观看 | 亚洲五月激情 | 在线 视频 亚洲 | 久久久久亚洲精品国产 | 欧美激情第十页 | 日韩免费小视频 |