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

  

相关文章
相关标签/搜索