iOS開發-開發總結(一)

 

之後的文章中,筆者會根據本身在開發中遇到的一些重點難點,進行簡單的總結和梳理,而且不會過多的解釋相關概念。編程

裏面可能會設置到Objective-C或者swift相關的各類技術,雖然比較雜,因此須要有必定的開發或者相關基礎,或者看起來比較雜,看的時候也可能會很亂的感受,可是隻要你能認真看完,相信您必定能發現意外的收穫!swift

 

好了,下面咱們就開始幹!app

 

OC2.0新特性:函數式編程

  • Nullability:(爲兼容swift中可選類型)
    • - (void)startWithCompletionBlock:(nullable void (^)(NSError * __nullable error))block;
    • nullable 可空 __nullable 不可空,當修飾的事變量的時候須要使用__
  • Lightweight Generics *:輕量級範性:
    • -(ObjectType)popObject;@interface 
    • Stack<objecttype: id> : NSObject</objecttype: id>
  • __kindof:返回值與強轉:
  • - (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier

 

編程模式:函數

面向對象編程OOP(最基本,最原始的編程模式)atom

函數式編程(響應式)ReactiveCocoa(請查看相關文檔)spa

面向值的編程VOPcode

向協議的編程POP對象

面向協議(簡單介紹):blog

複製代碼
 1 protocol ErrorPopoverRenderer {
 2 
 3     func presentError()
 4 
 5 } 
 6 
 7 extension ErrorPopoverRenderer where Self: UIViewController {
 8 
 9     func presentError() {
10 
11         //在這裏加默認實現,並提供ErrorView的默認參數。
12 
13     }
14 
15 }
複製代碼

 

 

 

關聯對象:分類中增長屬性

頭文件聲明一個屬性

 1 @property (nonatomic, copy) NSString *name; 

實現文件

導入<objc/message.h>

 定義一個靜態變量

 1 static void *key = (void *)@「iCocos」; 

 

重寫getter方法

 1 return objc_getAssociatedObject(self, key) 

 

重寫setter方法

 1 objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_COPY_NONATOMIC) 

 

swift中的寫法:

直接在拓展中(swift中的分類就是拓展)

  

 

循環引用

  • Blocks能夠訪問局部變量,可是不能修改
  • 若是修改局部變量,須要加__block 
複製代碼
1  __block int multiplier = 7;
2 
3      int (^myBlock)(int) = ^(int num) {
4 
5          multiplier ++;//這樣就能夠了
6 
7          return num * multiplier;
8 
9      };
複製代碼

 

 

__weak __typeof(&*self)weakSelf =self; 等同於__weak UIViewController *weakSelf =self;

相似以前的__unsafe_unretain(MRC中)

爲何不用__block 是由於經過引用來訪問self的實例變量 ,self被retain,block也是一個強引用,引發循環引用,用__week是弱引用,當self釋放時,weakSelf已經等於nil。

 

注意點:

weakSelf是爲了block不持有self,避免循環引用,而再聲明一個strongSelf是由於一旦進入block執行,就不容許self在這個執行過程當中釋放。block執行完後這個strongSelf會自動釋放,沒有循環引用問題

  

1 __weak __typeof(self)weakSelf = self; 
2 
3 self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{ 
4     __strong __typeof(weakSelf)strongSelf = weakSelf; 
5 
6 }];

 

關於Block這裏提醒一下,在使用block的時候除了要注意循環引用問題,還須要注意關於返回值和參數的傳遞!

 

三種常見循環引用:

  

1、parent-child相互持有、委託模式

複製代碼
1 @interface FTAppCenterMainViewController ()
2 
3 {
4 
5 }
6 
7  @property(weak,nonatomic) UITableView* myTableView;
8 
9 @end
複製代碼

 

這裏面的myTableView就使用了weak修飾符。

  1 @property (nonatomic, weak) iddelegate; 2 3  

【推薦方法】:

child只有parent的對象爲weak類型:

 1 @property (nonatomic, weak) iddelegate; 

 

2、block

看下面的代碼:

複製代碼
1 typedef void (^RequestNaviCallBack)(NSInteger naviCode,NSInteger httpCode,NSError * error);
2 
3 @interface FtNaviManager : NSObject
4 
5 {
6 
7 }
8 
9 @property (nonatomic, strong)   RequestNaviCallBack naviCallBack;
複製代碼

這是一個請求導航的類,類屬性持有了RequestNaviCallBack,這時,若是RequestNaviCallBack再持有self,必然形成循環引用。

【推薦方法】:

若是有循環引用,編譯器會提示警告。

若是對象沒有持有Block對象,那麼不會產生循環引用。若是對象持有了block對象,那麼在block引用self的時候這麼定義:

  1 __weak typeof(self) weakSelf = self;  

3、NSTimer 

複製代碼
@interface FtKeepAlive : NSObject

{

    NSTimer*              _keepAliveTimer; // 發送心跳timer

} 
複製代碼

//實現文件

 1 _keepAliveTimer = [NSTimer scheduledTimerWithTimeInterval:_expired target:self selector:@selector(keepLiveStart) userInfo:nil repeats:YES];  

類持有了_keepAliveTimer,_keepAliveTimer又持有了self,形成循環引用。

【推薦方法】:

NSTimer會持有對象,因此:在刪除對象以前,須要將timer的invalidate方法。

  

複製代碼
1 -(void)stopKeepAlive{
2 
3     [_keepAliveTimer invalidate];
4 
5     _keepAliveTimer = nil;
6 
7 }
複製代碼

 

@dynamic

  

相關文章
相關標籤/搜索