IOS多线程之Block编程
同一時候block本身也能夠被作為參數在方法和函數間傳遞。這就給予了block無限的可能。
? ??
對于閉包(block),有非常多定義。當中閉包就是可以讀取其他函數內部變量的函數,這個定義即接近本質又較好理解。對于剛接觸Block的同學,會認為有些繞,由于我們習慣寫這種程序main(){ funA();} funA(){funB();} funB(){.....}; 就是函數main調用函數A,函數A調用函數B... 函數們依次順序運行,但現實中不全是這種。比如項目經理M,手下有3個程序猿A、B、C,當他給程序猿A安排實現功能F1時,他并不等著A完畢之后。再去安排B去實現F2,而是安排給A功能F1,B功能F2,C功能F3,然后可能去寫技術文檔,而當A遇到問題時,他會來找項目經理M,當B做完時,會通知M。這就是一個異步運行的樣例。在這種情形下,Block便可大顯身手,由于在項目經理M,給A安排工作時。同一時候會告訴A若果遇到困難,怎樣能找到他報告問題(比如打他手機號)。這就是項目經理M給A的一個回調接口,要回掉的操作。比方接到電話,百度查詢后,返回網頁內容給A。這就是一個Block,在M交待工作時。已經定義好。而且取得了F1的任務號(局部變量),卻是在當A遇到問題時,才調用運行,跨函數在項目經理M查詢百度,獲得結果后回調該block。
block是一個特殊的OC對象, 它建立在棧上, 而不是堆上, 這么做一個是為性能考慮,還有就是方便訪問局部變量. 默認情況下block使用到的局部變量都會被復制,而不是保留. 所以它無法改變局部變量的值. 假設在變量面前加上__block, 那么編譯器回去不會復制變量, 而是去找變量的地址, 通過地址來訪問變量, 實際上就是直接操作變量. 另外塊是在棧上分配的, 所以一旦離開作用域, 就會釋放, 因此假設你要把快用在別的地方, 必需要復制一份. 所以在屬性定義一個快的時候須要使用copy: ?@property (nonatomic, copy) void (^onTextEntered)(NSString *enteredText); 塊是不能保留的, retain對塊沒有意義. 2 block 實現原理 Objective-C是對C語言的擴展,block的實現是基于指針和函數指針。 從計算語言的發展,最早的goto,高級語言的指針,到面向對象語言的block,從機器的思維,一步步接近人的思維,以方便開發者更為高效、直接的描寫敘述出現實的邏輯(需求)。 iOS中block實現的探究 談Objective-C Block的實現 3 block的使用 使用實例 A:cocoaTouch框架下動畫效果的Block的調用 動畫效果是IOS界面重要的特色之中的一個。當中CAAnimation是全部動畫對象的抽象父類。作為新人,使用較多的是UIView下的動畫方法(類方法)。使用UIView下的動畫,有以下幾個方法。
方法一:設置beginAnimations 當中memberView為須要加入的子視圖的視圖,mivc.view為子視圖,在使用的時候,須要將這兩個地方替換 須要注意的是。一定要使用[UIView commitAnimations];動畫才會生效 通過[UIView setAnimationDuration:1]; 設置持續時間。 方法二: 在IOS4.0后,我們有了新的方法,+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion,依舊是UIView的類方法,但使用到了Block對象。Block對象是一組指令,能夠傳遞(像變量一樣),能夠把它想像成C語言的函數指針。 [UIView transitionWithView:self.view duration:0.2 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{ [self.view addSubview:yellowView.view]; } completion:NULL]; B: 使用typed聲明block typedef void(^didFinishBlock) (NSObject *ob); 這就聲明了一個didFinishBlock類型的block, 然后便可用 @property (nonatomic,copy) didFinishBlock ?finishBlock; 聲明一個block對象,注意對象屬性設置為copy,接到block 參數時,便會自己主動復制一份。? __block是一種特殊類型。 使用該keyword聲明的局部變量,能夠被block所改變,而且其在原函數中的值會被改變。 C:1 使用block和使用delegate完畢托付模式有什么長處? block不同其他變量的原因在于它不是一個單一變量, 而是一個方法, 我們要傳遞的是一個代碼塊,而且這個代碼塊能夠存在參數, 這個參數并非在定義block的時候就賦予值, 而是我們在實際執行block的時候才賦予值.? 因此對于有參數的block,當我們傳遞過去的時候, 它的須要接收方提供對應的參數才干執行,? 這么做我們就能夠在A類為B類將來會發生的事件提前做優點理的方法,即使我們還沒有這些事件的詳細參數. 某種意義上將這樣就不須要兩者之間的托付關系. 托付關系就是B類發生一個事件后,通知A類,讓A類再針對這個事件進行一些處理 而使用block,則是A已經提前將這個事件的處理方法告訴了B類, 等時間發生的時候, B類無需通知A類, 直接執行實現設置好的處理方法(block)就可以. 假設你在執行一個方法的時候又想告訴這種方法在某一特定情況你還要怎么做的話, 就能夠使用Block. D: GCD: GCD主要使用block來取代托付模式,使程序變得簡潔,同一時候執行效率也得到提高. 復制代碼 static int clickNum = 0; self.Mylabel = [[UILabel alloc]init]; while (clickNum <20) { dispatch_async(dispatch_get_main_queue(), ^{ self.Mylabel.text = [NSString stringWithFormat:@"%d",clickNum++];//UI的繪制必須在主線程中 }); [NSThread sleepForTimeInterval:1]; } 復制代碼 關于block和GCD編程能夠參考這篇文章: 還有這篇文章 ARC和非ARC中block的差別: ARC下Block何時會從棧自己主動被拷貝到推, 以及__block和__weak的使用問題 因為Block是默認建立在棧上, 所以假設離開方法作用域, Block就會被丟棄, 在非ARC情況下, 我們要返回一個Block ,須要 [Block copy]; 在ARC下, 下面幾種情況, Block會自己主動被從棧拷貝到堆: 1.被運行copy方法 2.作為方法返回值 3.將Block賦值給附有__strong修飾符的id類型的類或者Blcok類型成員變量時 4.在方法名中含有usingBlock的Cocoa框架方法或者GDC的API中傳遞的時候. 對于非ARC下, 為了防止循環引用, 我們使用__block來修飾在Block中有用的對象: __block id blockSelf=self; self.blk=^{ NSLog(@"%@",blockSelf); ?//在非ARC下對于棧上的_block對象, Block不會對其復制, 只使用, 不會添加引用計數. }; 對于ARC下, 為了防止循環引用, 我們使用__weak來修飾在Block中有用的對象: __weak id weakSelf=self; self.blk=^{ NSLog(@"%@",weakSelf); }; 假設要在ARC下, 為了防止循環引用, 使用__block來修飾在Block中有用的對象,仍然會被retain, 所以須要多做一些設置 __block id blockSelf=self; self.blk=^{ NSLog(@"%@",blockSelf); self.blk=nil; ? //blk被釋放, blk僅僅有的blockSelf也就被釋放了 }; blk(); ? //而且一定要執行一次, 否則不能被釋放 這樣就使blk斷開了與blockSelf的持有關系. 這么多優點是能夠自己控制對self的持有時間. 只是在最新的ios版本號中, 這些會始終被已嘆號形式提示存在循環引用問題.? 這樣的書寫方式不被推薦. 除非你要在block中改動__block的指針指向. 事實上我們用使用__weak修飾符, 僅僅是不能改動對象本身, 可是能夠改動對象的屬性.?轉載于:https://www.cnblogs.com/liguangsunls/p/6702195.html
總結
以上是生活随笔為你收集整理的IOS多线程之Block编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在俱乐部首页看不到的团队成员(更新中..
- 下一篇: z17刷机miui12教程_MIUI12