iOS开发-开发总结(一)

以后的文章中,笔者会根据自己在开发中遇到的一些重点难点,进行简单的总结和梳理,并且不会过多的解释相关概念。

里面可能会设置到Objective-C或者swift相关的各种技术,虽然比较杂,所以需要有一定的开发或者相关基础,或者看起来比较杂,看的时候也可能会很乱的感觉,但是只要你能认真看完,相信您一定能发现意外的收获!

好了,下面我们就开始干!

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(最基本,最原始的编程模式)

函数式编程(响应式)ReactiveCocoa(请查看相关文档)

面向值的编程VOP

向协议的编程POP

面向协议(简单介绍):

复制代码
 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的时候除了要注意循环引用问题,还需要注意关于返回值和参数的传递!

三种常见循环引用:

  

一、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; 

二、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;  

三、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

  

原文地址:https://www.cnblogs.com/stronger-ios-lcx/p/5635044.html