C语言没加取缔符能否运行,老生常谈 之runtime!

runtime!runtime! runtime! 几乎每个iOS开发从业者在面试时都会被问到什么是runtime?!有什么用?!介于本人的一点从业经验和过往学习,下面就runtime做一个简单粗暴的介绍。

Objective-C 语言是一门动态语言,编译器不需要关心接受消息的对象是何种类型,接收消息的对象问题也要在运行时处理。

pragramming 层面的 runtime 主要体现在以下几个方面:

补充一个大家经常用的、但是很容易忽视的 runtime 应用吧:

动态获取 class 和 slector

NSClassFromString(@"MyClass");NSSelectorFromString(@"showShareActionSheet");

给分类添加属性和KVC/KVO了。

大多数情况下,我们是不会直接用 runtime 写业务代码的,所以,大部分时候,我们只会在一些平时用起来很方便的框架里面,看到有用到 runtime 的黑魔法(当然你也可以自己造轮子)。runtime 用起来的最大感受就是,底层写一堆 runtime,外面用起来超清爽!对于那些“代码艺术家”来说,简直是爽到爆。

我在项目中使用runtime比较少:

1.在category中添加属性

2.修改系统方法,如重写objectAtIndex方法阻止数组越界崩溃。

大概说说一下自己在开发中用到的一些基于 runtime 的开源框架吧,具体应用自己可以去看看源码:

1.Aspects(AOP必备,“取缔” baseVC,无侵入埋点)

2.MJExtension(JSON 转 model,一行代码实现 NSCoding 协议的自动归档和解档)

3.JSPatch(动态下发 JS 进行热修复)

4.NullSafe(防止因发 unrecognised messages 给 NSNull 导致的崩溃)

5.UITableView-FDTemplateLayoutCell(自动计算并缓存 table view 的 cell 高度)

6.UINavigationController+FDFullscreenPopGesture(全屏滑动返回)

runtime 的原理和用法可以看看官方文档:

Objective-C Runtime Programming GuideInteracting with the Runtime

20180212  更新

在引导页上使用了runtime

.h代码如下:

#import@interfaceUIViewController(KSGuid)//*实现引导页的控制器,外部不用调用即可实现GuidView,可以修改下面的图片*/@end/*这里是要展示的图片,修改即可,当然不止三个  1242 * 2208的分辨率最佳,如果在小屏手机上显示不全,最好要求UI重新设计图片*/#define ImageArray @[@"guid01",@"guid02",@"guid03",@"guid04"]/** pageIndicatorTintColor*/#define pageTintColor [[UIColor whiteColor] colorWithAlphaComponent:0.5];/** currentPageIndicatorTintColor*/#define currentTintColor [UIColor whiteColor];/*

如果要修改立即体验按钮的样式

重新- (UIButton*)removeBtn方法即可

*/

.m代码如下

#import"UIViewController+KSGuid.h"#import#define CollectionView_Tag 15#define RemoveBtn_tag 16#define Control_tag 17#define FIRST_IN_KEY @"FIRST_IN_KEY"@interfaceKSGuidViewCell:UICollectionViewCell@property(nonatomic,copy)NSString* imageName;@property(nonatomic,strong)UIImageView* imageView;@end@implementationKSGuidViewCell- (instancetype)initWithFrame:(CGRect)frame{self= [superinitWithFrame:frame];if(self) {        _imageView = [[UIImageViewalloc] initWithFrame:self.bounds];        _imageView.contentMode =UIViewContentModeScaleAspectFill;        _imageView.userInteractionEnabled =YES;        [self.contentView addSubview:_imageView];    }returnself;}- (void)setImageName:(NSString*)imageName{if(_imageName != imageName) {        _imageName = [imageNamecopy];    }    _imageView.image = [UIImageimageNamed:imageName];}@end/************************以上是KSGuidViewCell,以下才是UIViewController+KSGuid******************************/@implementationUIViewController(KSGuid)#pragma mark- #pragma mark 这里是退出的按钮- (UIButton*)removeBtn{//移除按钮样式UIButton* removeBtn = [UIButtonbuttonWithType:UIButtonTypeCustom];    [removeBtn addTarget:selfaction:@selector(removeGuidView) forControlEvents:UIControlEventTouchUpInside];    removeBtn.hidden = (self.imageArray.count !=1);    removeBtn.tag = RemoveBtn_tag;//注意这里的tag//***********************这里面可以自定义*******************************//CGFloatbtnW =128;CGFloatbtnH =35;CGFloatbtnX =CGRectGetMidX(self.view.frame) - btnW /2;CGFloatbtnY =CGRectGetMaxY(self.view.frame) *0.83;    removeBtn.frame =CGRectMake(btnX, btnY, btnW, btnH);        removeBtn.layer.cornerRadius =4;    removeBtn.layer.borderColor = [UIColorwhiteColor].CGColor;    removeBtn.layer.borderWidth =1.;        [removeBtn setTitle:@"进入婚匠"forState:UIControlStateNormal];    [removeBtn setTitleColor:[UIColorwhiteColor] forState:UIControlStateNormal];    removeBtn.titleLabel.font = [UIFontsystemFontOfSize:18.];//********************自定义结束**********************************//returnremoveBtn;}#pragma mark-#pragma mark 这里填充图片的名称- (NSArray*)imageArray{returnImageArray;}+ (void)load{NSString* versoin = [[[NSBundlemainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];NSString* versionCache = [[NSUserDefaultsstandardUserDefaults] objectForKey:FIRST_IN_KEY];//启动时候首先判断是不是第一次if([versoin isEqualToString:versionCache]) {return;    }//以下代码只在程序安装初次运行时候执行staticdispatch_once_tonceToken;dispatch_once(&onceToken, ^{                Method method1 = class_getInstanceMethod(self.class,@selector(viewDidLoad));        Method method2 = class_getInstanceMethod(self.class,@selector(guidViewDidLoad));BOOLdidAddMethod =        class_addMethod(self.class,@selector(viewDidLoad),                        method_getImplementation(method2),                        method_getTypeEncoding(method2));if(didAddMethod) {            class_replaceMethod(self.class,@selector(guidViewDidLoad),                                method_getImplementation(method1),                                method_getTypeEncoding(method1));        }else{            method_exchangeImplementations(method1, method2);        }    });}- (void)guidViewDidLoad{staticdispatch_once_tonceToken;dispatch_once(&onceToken, ^{//这里的代码只在程序安装初次打开,并且在第一个控制器里面执行//初始化视图[selfsetupSubViews];    });//这是调用工程里面的viewDidLoad[selfguidViewDidLoad];}#pragma mark- #pragma mark 初始化视图- (void)setupSubViews{//界面样式UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayoutalloc] init];    flowLayout.itemSize = [UIScreenmainScreen].bounds.size;    flowLayout.minimumLineSpacing =0;    flowLayout.minimumInteritemSpacing =0;    flowLayout.sectionInset =UIEdgeInsetsZero;    flowLayout.scrollDirection =UICollectionViewScrollDirectionHorizontal;UICollectionView* collectionView = [[UICollectionViewalloc]                      initWithFrame:self.view.bounds                      collectionViewLayout:flowLayout];    collectionView.dataSource =self;    collectionView.delegate =self;    collectionView.pagingEnabled =YES;    collectionView.showsVerticalScrollIndicator =NO;    collectionView.showsHorizontalScrollIndicator =NO;    collectionView.backgroundColor = [UIColorwhiteColor];    [collectionView registerClass:[KSGuidViewCellclass] forCellWithReuseIdentifier:@"KSGuidViewCell"];        collectionView.tag = CollectionView_Tag;    [self.view addSubview:collectionView];        [self.view addSubview:self.removeBtn];UIPageControl* control = [[UIPageControlalloc] init];CGFloatcontrolW =170;CGFloatcontrolH =20;CGFloatcontrolX =CGRectGetMidX(self.view.frame) - controlW /2;CGFloatcontrolY =CGRectGetMaxY(self.view.frame) -38;    control.frame =CGRectMake(controlX, controlY, controlW, controlH);    control.numberOfPages = ImageArray.count;    control.pageIndicatorTintColor = pageTintColor;    control.currentPageIndicatorTintColor = currentTintColor;        control.tag = Control_tag;    [self.view addSubview:control];}#pragma mark-#pragma mark UICollectionViewDataSource- (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section{returnself.imageArray.count;}- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath{        KSGuidViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"KSGuidViewCell"forIndexPath:indexPath];    cell.imageName =self.imageArray[indexPath.row];returncell;}- (void)scrollViewDidScroll:(UIScrollView*)scrollView{NSUIntegerindex = scrollView.contentOffset.x /CGRectGetWidth(self.view.frame);    [self.view viewWithTag:RemoveBtn_tag].hidden = (index !=self.imageArray.count -1);UIPageControl* control =[self.view viewWithTag:Control_tag];    control.currentPage = index;    }- (void)removeGuidView{NSString* versoin = [[[NSBundlemainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];    [[NSUserDefaultsstandardUserDefaults] setObject:versoin forKey:FIRST_IN_KEY];    [[NSUserDefaultsstandardUserDefaults] synchronize];        [[self.view viewWithTag:Control_tag] removeFromSuperview];    [[self.view viewWithTag:RemoveBtn_tag] removeFromSuperview];    [[self.view viewWithTag:CollectionView_Tag] removeFromSuperview];}@end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值