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