一 block delegate優點 block 注意事項:ios
1)共同的做用: Block 和 Delegate中的方法均可以理解成回調函數,當某件事情發生的時候取執行一段代碼片斷安全
2)Block(代碼塊) 優勢:是一種輕量級的回調,可以直接訪問上下文,使用塊的地方和塊的實現地方在同一個地方,使得代碼組織更加連貫併發
3.Delegate(代理) 相對來講是重量級的回調, 缺點: 因方法的聲明和實現分離開來,代碼的連貫性不是很好 代理不少時候須要存儲一些臨時數據 優勢: 代理的回調函數能夠是一組多個函數,在不一樣的時機調用不一樣的回調函數異步
注意事項: 1,block 在實現時就會對它引用到的它所在方法中定義的棧變量進行一次只讀拷貝,而後在 block 塊內使用該只讀拷貝。函數
2,非內聯(inline) block 不能直接訪問 self,只能經過將 self 看成參數傳遞到 block 中才能使用,而且此時的 self 只能經過 setter 或 getter 方法訪問其屬性,不能使用句點式方法。但內聯 block 不受此限制。oop
3,使用 weak–strong dance 技術來避免循環引用 函數體執行結束後 函數體有個自動釋放池post
三.內存循環引用場景 動畫
• 定時器(NSTimer): NSTimer常常會被做爲某個類的成員變量,而NSTimer初始化時要指定self爲target,容易形成循環引用(self->timer->self)。 另外,若timer一直處於validate的狀態,則其引用計數將始終大於0,所以在再也不使用定時器之後,應該先調用invalidate方法, 說白了就是必定要移除定時器.ui
• block的使用: block在copy時都會對block內部用到的對象進行強引用(ARC)或者retainCount增1(非ARC)。在ARC與非ARC環境下對block使用不當都會引發循環引用問題, 通常表現爲,某個類將block做爲本身的屬性變量,而後該類在block的方法體裏面又使用了該類自己,簡單說就是self.someBlock = Type var{[self dosomething];或者self.otherVar = XXX;或者_otherVar = …};出現循環的緣由是:self->block->self或者self->block->_ivar(成員變量)spa
代理(delegate): 在委託問題上出現循環引用問題已是老生常談了,規避該問題的殺手鐗也是簡單到哭,簡單的來講:聲明delegate時請用assign(MRC)或者weak(ARC)
四.ios中如何讓uibutton內的非矩形區域響應uitouch
舉個例子,純用button是確定不行的了。好比說一個正方形邊長爲D,內中心有一個直徑也爲D的圓,我要求圓內科響應,圓外正方形部分不響應。圓的直徑r = D/2.f; 給正方形_view添加UITapGestrureRecongnizer *tap tap.delegate = self; [_view addGestru...er:tap]; - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { CGPoint point = [touch locationInView:_view]; //圓原點座標爲 CGFloat x1 = r; CGFloat y2 = r; // CGFloat x2 = point.x; CGFloat y2 = point.y; if((y2-y1)²+(x2-x1)² < r²) { //圓內,響應點擊 return YES; }else { return NO; } } 兩點間的距離 d,則 d² = (y2-y1)²+(x2-x1)²;
5、詳解 CALayer 和 UIView 的區別和聯繫
1.首先UIView能夠響應事件,Layer不能夠.
2.View和CALayer的Frame映射及View如何建立CALayer. 一個 Layer 的 frame 是由它的 anchorPoint,position,bounds,和 transform 共同決定的,而一個 View 的 frame 只是簡單的返回 Layer的 frame,一樣 View 的 center和 bounds 也是返回 Layer 的一些屬性。(PS:center有些特列)
3.UIView主要是對顯示內容的管理而 CALayer 主要側重顯示內容的繪製。 4.在作 iOS 動畫的時候,修改非 RootLayer的屬性(譬如位置、背景色等)會默認產生隱式動畫,而修改UIView則不會。
總接來講就是以下幾點: 每一個 UIView 內部都有一個 CALayer 在背後提供內容的繪製和顯示,而且 UIView 的尺寸樣式都由內部的 Layer 所提供。二者都有樹狀層級結構,layer 內部有 SubLayers,View 內部有 SubViews.可是 Layer 比 View 多了個AnchorPoint 在 View顯示的時候,UIView 作爲 Layer 的 CALayerDelegate,View 的顯示內容由內部的 CALayer 的 display CALayer 是默認修改屬性支持隱式動畫的,在給 UIView 的 Layer 作動畫的時候,View 做爲 Layer 的代理,Layer 經過 actionForLayer:forKey:向 View請求相應的 action(動畫行爲) layer 內部維護着三分 layer tree,分別是 presentLayer Tree(動畫樹),modeLayer Tree(模型樹), Render Tree (渲染樹),在作 iOS動畫的時候,咱們修改動畫的屬性,在動畫的實際上是 Layer 的 presentLayer的屬性值,而最終展現在界面上的實際上是提供 View的modelLayer 二者最明顯的區別是 View能夠接受並處理事件,而 Layer 不能夠
6、GCD隊列
1.串行隊列:Dispatch Queues或者Serial Queues
2.併發隊列 :Concurrent Queues
3.主隊列:main dispatch Queue
針對以上3種隊列:concurrent queues和main queue都是由系統生成並且 dispatch_suspend, dispatch_resume, dispatch_set_context這些函數對他們無效。 可是咱們的應用不是簡單的同步也異步的運行,應用常常是混合的。 好比咱們要task1 task2 task3都運行完成後才能異步運行task4 task5 task6咱們該怎麼作呢?這裏咱們能夠引入group的概念。
七.strong,weak, unsafe_unretained往往都是用來聲明屬性的,若是想聲明臨時變量就得用__strong, __weak, __unsafe_unretained, __autoreleasing, 其用法與上面介紹的相似。
_bridge做用是類型轉換
1.__bridge:CF和OC對象轉化時只涉及對象類型不涉及對象全部權的轉化;
2.__bridge_transfer:經常使用在講CF對象轉換成OC對象時,將CF對象的全部權交給OC對象,此時ARC就能自動管理該內存;(做用同CFBridgingRelease())
3.__bridge_retained:(與__bridge_transfer相反)經常使用在將OC對象轉換成CF對象時,將OC對象的全部權交給CF對象來管理;(做用同CFBridgingRetain())
八.Runloop的寄生於線程:一個線程只能有惟一對應的runloop;但這個根runloop裏能夠嵌套子runloops; 自動釋放池寄生於Runloop:程序啓動後,主線程註冊了兩個Observer監聽runloop的進出與睡覺。一個最高優先級OB監測Entry狀態;一個最低優先級OB監聽BeforeWaiting狀態和Exit狀態。 線程(建立)-->runloop將進入-->最高優先級OB建立釋放池-->runloop將睡-->最低優先級OB銷燬舊池建立新池-->runloop將退出-->最低優先級OB銷燬新池-->線程(銷燬)
九.copy strong 區別
若是通常狀況下,咱們都不但願字串的值跟着mStr變化,因此咱們通常用copy來設置string的屬性。
若是但願字串的值跟着賦值的字串的值變化,可使用strong,retain。
注意:上面的狀況是針對於當把NSMutableString賦值給NSString的時候,纔會有不一樣,若是是賦值是NSString對象,那麼使用copy仍是strong,結果都是同樣的,由於NSString對象根本就不能改變自身的值,他是不可變的。
把一個對象賦值給一個屬性變量,當這個對象變化了,若是但願屬性變量變化就使用strong屬性,若是但願屬性變量不跟着變化,就是用copy屬性。
對源頭是NSMutableString的字符串,retain僅僅是指針引用,增長了引用計數器,這樣源頭改變的時候,用這種retain方式聲明的變量(不管被賦值的變量是可變的仍是不可變的),它也會跟着改變;而copy聲明的變量,它不會跟着源頭改變,它其實是深拷貝。
對源頭是NSString的字符串,不管是retain聲明的變量仍是copy聲明的變量,當第二次源頭的字符串從新指向其它的地方的時候,它仍是指向原來的最初的那個位置,也就是說其實兩者都是指針引用,也就是淺拷貝。
另外說明一下,這二者對內存計數的影響都是同樣的,都會增長內存引用計數,都須要在最後的時候作處理。
其實說白了,對字符串爲啥要用這兩種方式?我以爲仍是一個安全問題,好比聲明的一個NSString *str變量,而後把一個NSMutableString *mStr變量的賦值給它了,若是要求str跟着mStr變化,那麼就用retain;若是str不能跟着mStr一塊兒變化,那就用copy。而對於要把NSString類型的字符串賦值給str,那兩都沒啥區別。不會影響安全性,內存管理也同樣。