youmi

内存管理.md
Code.m

项目

  • 你项目中遇到什么问题怎么解决的

    1,one,window scrollview top1 点击 状态栏 上滑顶部
    2, 截取 cell 点击 计算点击商品次数
    3, uitableview 滑动卡
    
    4,后台用什么数据库
    5,用户订单提醒 提醒用什么消息推送模式
    
    
    你为什么从外企离职 -想获取更大的发展空间,在里面 感到很孤独 不想为别人的想法买单,想为自己买单
    

iOS调试

  • [iOS SDK:iOS调试技巧 .mhtml](iOS SDK:iOS调试技巧 .mhtml)

        使用console检查app状态
        进行日志记录,并熟练的驾驭NSLog
        使用对象的生命周期来跟踪内存的使用
    

UIAlertController

UIAlertController.mhtml

并不提倡在iOS 8中使用UIAlertView,取而代之的是UIAlertController,同创建UIAlertView相比,我们无需指定代理,也无需在初始化过程中指定按钮。不过要特别注意第三个参数,要确定您选择的是对话框样式还是上拉菜单样式。

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"标题" message:@"这个是UIAlertController的默认样式" preferredStyle:UIAlertControllerStyleAlert];

[self presentViewController:alertController animated:YES completion:nil];

UIAlertAction *resetAction = [UIAlertAction actionWithTitle:@"重置" style:UIAlertActionStyleDestructive handler:nil];
[alertController addAction:resetAction];

渲染(iOS性能优化小结)

[一次 TableView 性能优化.mhtml](一次 TableView 性能优化.mhtml)

  • [iOS 保持界面流畅的技巧 _ Garan no dou](iOS 保持界面流畅的技巧 _ Garan no dou.mhtml)

    预排版
    预渲染
    异步绘制
    全局并发控制
    
  • [提升UITableView性能-复杂页面的优化 _ 土土哥的技术Blog.mhtml](提升UITableView性能-复杂页面的优化 _ 土土哥的技术Blog.mhtml)

    主要分为以下几点:
    
    只定义一种Cell。
    提前计算并缓存每个Cell的高度。
    提前创建真正显示的、需要加工的数据并缓存。
    缓存View!
    其它。
    
  • UIImage缓存取舍

    UIImage使用
    在Main Thread中发现不同动画场景中Image IO 开销和耗时所占比例均不一,在UIImage元素较多总体叠加耗时也会占用一定比例.内存开销也会明显增高.
    
    UIImage加载图片方式一般有两种:
    
    A:imagedNamed初始化
    
    B:imageWithContentsOfFile初始化
    二者不同之处在于,imageNamed默认加载图片成功后会内存中缓存图片,这个方法用一个指定的名字在系统缓存中查找并返回一个图片对象.如果缓存中没有找到相应的图片对象,则从指定地方加载图片然后缓存对象,并返回这个图片对象.
    
    而imageWithContentsOfFile则仅只加载图片,不缓存.
    
    大量使用imageNamed方式会在不需要缓存的地方额外增加开销CPU的时间来做这件事.当应用程序需要加载一张比较大的图片并且使用一次性,那么其实是没有必要去缓存这个图片的,用imageWithContentsOfFile是最为经济的方式,这样不会因为UIImage元素较多情况下,CPU会被逐个分散在不必要缓存上浪费过多时间.
    
    使用场景需要编程时,应该根据实际应用场景加以区分,UIimage虽小,但使用元素较多问题会有所凸显.
    
  • [iOS应用性能调优的25个建议和技巧](iOS应用性能调优的25个建议和技巧 - 博客 - 伯乐在线.mhtml)

    入门级(这是些你一定会经常用在你app开发中的建议)
    
    1. 用ARC管理内存
    2. 在正确的地方使用reuseIdentifier
    3. 尽可能使Views不透明
    4. 避免庞大的XIB
    5. 不要block主线程
    6. 在Image Views中调整图片大小
    7. 选择正确的Collection
    8. 打开gzip压缩
    中级(这些是你可能在一些相对复杂情况下可能用到的)
    
    9. 重用和延迟加载Views
    10. Cache, Cache, 还是Cache!
    11. 权衡渲染方法
    12. 处理内存警告
    13. 重用大开销的对象
    14. 使用Sprite Sheets
    15. 避免反复处理数据
    16. 选择正确的数据格式
    17. 正确地设定Background Images
    18. 减少使用Web特性
    19. 设定Shadow Path
    20. 优化你的Table View
    21. 选择正确的数据存储选项
    进阶级(这些建议只应该在你确信他们可以解决问题和得心应手的情况下采用)
    
    22. 加速启动时间
    23. 使用Autorelease Pool
    24. 选择是否缓存图片
    25. 尽量避免日期格式转换
    

内存管理

  • IOS中堆和栈的区别

    对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。
    碎片问题:
    对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出
    分配方式:
    堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。
    分配效率:
    栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。
    
  • 内存管理.md

动画

  • setNeedsDisplay和setNeedsLayout

    1,UIView的setNeedsDisplay和setNeedsLayout方法
      首先两个方法都是异步执行的。而setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到  UIGraphicsGetCurrentContext,就可以画画了。而setNeedsLayout会默认调用layoutSubViews,
     就可以  处理子视图中的一些数据。
    综上所诉,setNeedsDisplay方便绘图,而layoutSubViews方便出来数据。
    layoutSubviews在以下情况下会被调用:
    1、init初始化不会触发layoutSubviews。
    2、addSubview会触发layoutSubviews。
    3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。
    4、滚动一个UIScrollView会触发layoutSubviews。
    5、旋转Screen会触发父UIView上的layoutSubviews事件。
    6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。
    7、直接调用setLayoutSubviews。
    
    drawRect在以下情况下会被调用:
     1、如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。drawRect调用是在Controller->loadView, Controller->viewDidLoad 两方法之后掉用的.所以不用担心在控制器中,这些View的drawRect就开始画了.这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量值).
    2、该方法在调用sizeToFit后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。
    3、通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。
    4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。
    以上1,2推荐;而3,4不提倡
    
    drawRect方法使用注意点:
    1、若使用UIView绘图,只能在drawRect:方法中获取相应的contextRef并绘图。如果在其他方法中获取将获取到一个invalidate的ref并且不能用于画图。drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay 或者 setNeedsDisplayInRect,让系统自动调该方法。
    2、若使用calayer绘图,只能在drawInContext: 中(类似于drawRect)绘制,或者在delegate中的相应方法绘制。同样也是调用setNeedDisplay等间接调用以上方法
    3、若要实时画图,不能使用gestureRecognizer,只能使用touchbegan等方法来掉用setNeedsDisplay实时刷新屏幕
    

[iOS 事件处理机制与图像渲染过程.mhtml](iOS 事件处理机制与图像渲染过程.mhtml)

     iOS RunLoop都干了什么
    iOS 为什么必须在主线程中操作UI
    事件响应
    CALayer
    CADisplayLink 和 NSTimer
    iOS 渲染过程
    渲染时机
    CPU 和 GPU渲染
    Core Animation
    Facebook Pop介绍
    AsyncDisplay介绍
    参考文章

如何对使用了autolayout的UIView添加动画

    在以前我们经常通过对一个view的frame的修改产生view移动的动画效果,那么在使用了autolayout的view世界中我 们该如何实现相同的效果呢?答案是,我们“将计就计”,通过改变这个view上的某个约束constraint然后在uiview的animation block中触发layout来实现。

[Core Animation & Facebook’s pop](Core Animation & Facebook’s pop.mhtml)

    Core Animation、UIView动画(其实是对Core Animation的一种封装)相关资料。不小心看到一群大神正在热烈讨论,钻一进去一看,原来是 POP (潜意识:Facebook出品必属精品),这还学什么Core Animation,果断pod一个来玩玩,于是你就左手CA,右手 POP 开森地把玩起来了。

AutoLayout还能做动画.mhtml

    是的,很明确的告诉各位看官,AutoLayout的确能做动画。AutoLayout是用来做各种约束,是用来适配不同屏幕的,那么当我们改变其中某些约束并讲这个改变的过程以缓慢的速度显示,那么是不是就实现了动画
  • 你平时用什么做动画

    1.UIView首末式动画(实现渐变效果)
    
    [UIView animateWithDuration:...]
    
    在修改了自动布局的约束之后,执行下面代码实现动画效果 [UIView animateWithDuration:1.0 animations:^{ 
    [添加了约束的view layoutIfNeeded]; 
    }];
    
    2.UIImageView的startAnimating系列方法播放帧动画。
    
    3.当对非Root Layer的部分属性(可动画属性)进行修改时,默认会自动产生一些动画效果(隐式动画)
    4.核心动画:
    
    CABasicAnimation
    CAKeyframeAnimation帧动画
    CATransition转场动画(UIView也有转场动画)
    CAAnimationGroup组动画
    
    5.动图GIF实现
    
    UIImage *image=[UIImage animatedImageWithImages: duration:];
    
    

MJRefresh

MJRefresh原理分析

    大部分的下拉刷新控件,都是用contentInset实现的。默认情况下,如果一个UIScrollView的左上角在导航栏的正下方,那么它的contentInset是64,而contentOffset是-64。继续下拉的话,contentOffset就会越来越小,如果上滑,contentOffset就会增大,直到左上角达到屏幕的左上角时,contentOffset刚好为0
    默认情况下,如果下拉一个UIScrollView,在松手之后,会弹回初始的位置(导航栏下方)。而大部分的下拉刷新控件,都是将自己放在UIScrollView的上方,起始y设置成负数,所以平时不会显示出来,只有下拉的时候才会出现,放开又会弹回去。然后在loading的时候,临时把contentInset增大,相当于把UIScrollView往下挤,于是下拉刷新的控件就会显示出来,然后刷新完成之后,再把contentInset改回原来的值,实现回弹的效果
    基本上,MJRefresh也是这么实现的

网络 多线程

  • 网络

    • NSURLConnection(iOS9过期)

      可以有两个办法让NSURLConnection在子线程中运行,即将NSURLConnection加入到run loop或者NSOperationQueue中去运行。

    • NSURLSession

      在普通的应用场景下NSURLSession与NSURLConnection相比没有什么优势,但是在程序切换到后台之后Background的Session就显得更加灵活了。

  • [NSURLSession使用说明及后台工作流程分析 - CocoaChina 苹果开发中文站 - 最热的iPhone开发社区 最热的苹果开发社区 最热的iPad开发社区.mhtml](NSURLSession使用说明及后台工作流程分析 - CocoaChina 苹果开发中文站 - 最热的iPhone开发社区 最热的苹果开发社区 最热的iPad开发社区.mhtml)

    NSURLSession提供的功能:
    1.通过URL将数据下载到内存
    2.通过URL将数据下载到文件系统
    3.将数据上传到指定URL
    4.在后台完成上述功能
    
  • 多线程

    • NSThread
    • GCD (单例模式)
    • NSOperation

      NSOperation实质是封装了需要并发运行的代码,一些主要接口和NSThread基本相同,可以看做没有线程运行能力的thread类的抽象。参考NSThread,NSOperation的一些相同的接口有:

    • [iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD .mhtml](iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD .mhtml)

      iOS有三种多线程编程的技术,分别是:
      (一)NSThread
      (二)Cocoa NSOperation
      (三)GCD(全称:Grand Central Dispatch)

      这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。

      三种方式的优缺点介绍
      1)NSThread:
      优点:NSThread 比其他两个轻量级
      缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销

      2)Cocoa NSOperation:
      优点:不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。
      Cocoa operation 相关的类是 NSOperation ,NSOperationQueue。
      NSOperation是个抽象类,使用它必须用它的子类,可以实现它或者使用它定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。
      创建NSOperation子类的对象,把对象添加到NSOperationQueue队列里执行。

      3)GCD:
      Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。在iOS4.0开始之后才能使用。GCD是一个替代诸如NSThread, NSOperationQueue, NSInvocationOperation等技术的很高效和强大的技术。现在的iOS系统都升级到7了,所以不用担心该技术不能使用。

    • [IOS多线程NSThread,NSOperation,Grand Central Dispatch.mhtml](IOS多线程NSThread,NSOperation,Grand Central Dispatch.mhtml)

iOS中消息的传递机制

消息的传递机制

    本文中,会经常提及接收者[recipient]和发送者[sender]。在消息传递机制中具体是什么意思,我们可以通过一个示例来解释:一个table view是发送者,而它的delegate就是接收者。Core Data managed object context是notification的发送者,而获取这些notification的主体则是接收者。一个滑块(slider)是action消息的发送者,而在代码里面对应着实现这个action的responder就是接收者。对象中的某个属性支持KVO,那么谁修改这个值,谁就是发送者,对应的观察者(observer)则是接收者

事件传递 响应者链条

[iOS开发中的事件处理](事件传递,响应者链条- - iPhone手机开发技术文章 - 红黑联盟.mhtml)

  • 事件传递的完整过程

        先将事件对象由上往下传递(由父控件传递给子控件),找到最合适的控件来处理这个事件。 调用最合适控件的touches….方法 如果调用了[super touches….];就会将事件顺着响应者链条往上传递,传递给上一个响应者 接着就会调用上一个响应者的touches….方法
    
    • 响应者链条的事件传递过程

      如果view是控制器的view,就传递给控制器;如不是,则将其传递给它的父视图 在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理 如果window对象也不处理,则其将事件或消息传递给UIApplication对象 如果UIApplication也不能处理该事件或消息,则将其丢弃

sizeClass AutoLayout

  • iOS8推出的Size Class,可以让我们在一个工程的storyboard中进行所有尺寸屏幕的适配,不仅是iPhone 4s-5/5s-6-6 Plus,还包括iPad界面.它引入了一种新的概念,抛弃传统意义上我们适配时所谓的具体宽高尺寸,把屏幕的宽和高分别分成两种情况:Compact-紧凑, Regular-正常(Any-任意,其实就是这2种的组合,所以我没分成3种情况).搭配起来是3*3,
  • :Compact-紧凑, Regular-正常(Any-任意

     可以总结为: 
    
    如果项目不支持横屏显示,使用w:Compact h:Regular(或者直接取消使用Size Class) 
    如果项目支持横屏显示,使用w:Compact h:Regular+w:Any h:Compact 
    对于一些公有的约束(任意组合中都适用),一般放在w:Any h:Any中设置 
    iPad同理
    
  • autolayout

    直接说以后都应该使用storyboard+autolayout感觉是不负责的说法,但是深入思考autolayout是很有必要的!
    
    如下情况使用autolayout会有帮助: 
    
    当需要展示的内容很多并且尺寸不固定; 
    程序需支持屏幕旋转(主要是iPad程序,iPhone程序横屏的场景有点非主流,也不排除..手游..); 
    程序通用于iPhone和iPad(最重要的吧). 
    但storyboard中使用autolayout有利有弊,好处当然是可视化,实现简单功能很节省时间,但也有弊端,例如不小心移动一个控件就会让弄乱那些约束或者控件一多加上自定义的XXXXXXXX 
    
  • autolayout 三种方式

    VFL:苹果开发团队可能觉得添加单个constraint的API比较长,于是就有了VFL(Visual format language)
    Masonry:
    手动:

子线程 runLoop

  • [–零–从程序启动开始到view显示:](【iOS程序启动与运转】- RunLoop个人小结 - 简书.mhtml)

           start->(加载framework,动态静态链接库,启动图片,Info.plist等)->main函数->UIApplicationMain函数:
    
          - 初始化UIApplication单例对象
          - 初始化AppDelegate对象,并设为UIApplication对象的代理
          - 检查Info.plist设置的xib文件是否有效,如果有则解冻Nib文件并设置outlets,创建显示key window、rootViewController、与rootViewController关联的根view(没有关联则看rootViewController同名的xib),否则launch之后由程序员手动加载。
          - 建立一个主事件循环,其中包含UIApplication的Runloop来开始处理事件。
        UIApplication:
        1、通过window管理视图;
        2、发送Runloop封装好的control消息给target;
        3、处理URL,应用图标警告,联网状态,状态栏,远程事件等。
        AppDelegate:
        管理UIApplication生命周期和应用的五种状态(notRunning/inactive/active/background/suspend)。
        Key Window:
        1、显示view;
        2、管理rootViewcontroller生命周期;
        3、发送UIApplication传来的事件消息给view。
        rootViewController:
        1、管理view(view生命周期;view的数据源/代理;view与superView之间事件响应nextResponder的“备胎”);
        2、界面跳转与传值;
        3、状态栏,屏幕旋转。
        view:
        1、通过作为CALayer的代理,管理layer的渲染(顺序大概是先更新约束,再layout再display)和动画(默认layer的属性可动画,view默认禁止,在UIView的block分类方法里才打开动画)。layer是RGBA纹理,通过和mask位图(含alpha属性)关联将合成后的layer纹理填充在像素点内,GPU每1/60秒将计算出的纹理display在像素点中。
        2、布局子控件(屏幕旋转或者子视图布局变动时,view会重新布局)。
        3、事件响应:event和guesture。
        插播控制器生命周期
        runloop:
        1、(要让马儿跑)通过do-while死循环让程序持续运行:接收用户输入,调度处理事件时间。
        2、(要让马儿少吃草)通过mach_msg()让runloop没事时进入trap状态,节省CPU资源。
    
  • IOS在子线程中使用定时器,将定时器添加至RunLoop中

         runloop是一个看似很神秘的东西,其实一点也不神秘。每个线程都有一个实际已经存在的runloop。比如我们的主线程,在主函数的UIApplication中:
    
        1 UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]))
        系统就为我们将主线程的main runloop隐式的启动了。runloop顾名思义就是一个“循环”,他不停地运行,从程序开始到程序退出。正是由于这个“循环”在不断地监听各种事件,程序才有能力检测到用户的各种触摸交互、网络返回的数据才会被检测到、定时器才会在预定的时间触发操作……
    
        runloop只接受两种任务:输入源和定时源。本文中说的就是定时源。默认状态下,子线程的runloop中没有加入我们自己的源,那么我们在子线程中使用自己的定时器时,就需要自己加到runloop中,并启动该子线程的runloop,这样才能正确的运行定时器。
    
  • [在子线程中使用runloop,正确操作NSTimer计时的注意点 三种可选方法 ](在子线程中使用runloop,正确操作NSTimer计时的注意点 三种可选方法 - FaceYe.mhtml)

    使用了简单的在主线程中调用:
    
    1 + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
    的方法。但是当每0.01秒进行一次repeat操作时,NSTimer是不准的,严重滞后,而改成0.1秒repeat操作,则这种滞后要好一些。
    
    导致误差的原因是我在使用“scheduledTimerWithTimeInterval”方法时,NSTimer实例是被加到当前runloop中的,模式是NSDefaultRunLoopMode。而“当前runloop”就是应用程序的main runloop,此main runloop负责了所有的主线程事件,这其中包括了UI界面的各种事件。当主线程中进行复杂的运算,或者进行UI界面操作时,由于在main runloop中NSTimer是同步交付的被“阻塞”,而模式也有可能会改变。因此,就会导致NSTimer计时出现延误。
    
    解决这种误差的方法,一种是在子线程中进行NSTimer的操作,再在主线程中修改UI界面显示操作结果;另一种是仍然在主线程中进行NSTimer操作,但是将NSTimer实例加到main runloop的特定mode(模式)中。避免被复杂运算操作或者UI界面刷新所干扰。
    
  • [深入理解RunLoop _ Garan no dou.mhtml](深入理解RunLoop _ Garan no dou.mhtml)

    RunLoop 的概念
    RunLoop 与线程的关系
    RunLoop 对外的接口
    RunLoop 的 Mode
    RunLoop 的内部逻辑
    RunLoop 的底层实现
    苹果用 RunLoop 实现的功能
    AutoreleasePool
    事件响应
    手势识别
    界面更新
    定时器
    PerformSelecter
    关于GCD
    关于网络请求
    RunLoop 的实际应用举例
    AFNetworking
    AsyncDisplayKit
    
  • [iOS并发编程(Concurrency Programming)系列之一:Run Loop.mhtml](iOS并发编程(Concurrency Programming)系列之一:Run Loop.mhtml)

    Run Loop主要有以下三个应用场景:
    1 可维护生命周期的线程
    2 长驻线程,用于执行一些预期会一直存在的任务
    3 在一定时间内监听某种事件,或执行某种任务的线程
    
  • NSRunLoop面试问题-重点

        常驻线程应用场景:
    
          举个例子,某个应用需要频繁的下载或者上传大容量的音频或者视频,默认主线程就是一个常驻线程,但是这种耗时操作肯定要转移到子线程中取完成。比如说微信\陌陌,用户有时候需要一直发送语音,如果每发送一条语音就开启一个自子线程,那么频繁的开启、销毁线极大的消耗手机性能,所以常驻线程就应运而生。
    
        如何创建常驻线程?
    

runtime 实际应用

  • 1, 利用runtime遍历模型对象的所有属性, 根据属性名从字典中取出对应的值, 设置到模型的属性上

    iOS开发之runtime的运用-获取当前网络状态

    通过runtime获取一些苹果官方不想让你拿到的东西,比如,状态栏内部的控件属性,我们可以通过runtime - kvc 获得
    通过runtime带你一步步拿到状态栏中显示网络状态的控件,然后通过监测该控件的属性来获取当前精确网络状态,比如2G/3G/4G/WIFI。
    
    1,编写运行时代码,获取到当前应用程序的所有成员变量
    2,通过KVC取出它里面的所有子视图
    
    UITabBar item 位置
    
  • 2, catagory之所以不能给一个类添加属性是因为编译器在最开始就已经分配好了内存,所以无法在添加任何实例变量,但是有了runtime,可以用objc_setAssociatedObject 和 objc_setAssociatedObject 来动态的为uiview加上badge这样的属性.

用runtime为分类加badged属性.mhtml

    许多的地方都有一个红色提醒标识.于是就想着做一个类似Badge的控件.开始想自定义一个这样的控件,但是发现如果要实现一个类,这样其他已有的视图可复用性太低,最后打算给uiview写一个cagetory.
  • 3, iOS 记录 cell/button 点击次数

    通过runtime为UIButton的分类添加 计数属性 和 被点击button的属性 储存 哪个button被点击了几次,在 addTarget 这个方法中 用 objc_msgSend 拦截button点击 并调用super重写 action:方法

ClickCountOfButton

  • 4, 在开发项目中,会有这样变态的需求:

    推送:根据服务端推送过来的数据规则,跳转到对应的控制器
    
    feeds列表:不同类似的cell,可能跳转不同的控制器(嘘!产品经理是这样要求:我也不确定会跳转哪个界面哦,可能是这个又可能是那个,能给我做灵活吗?根据后台返回规则任意跳转?)
    

[iOS 万能跳转界面方法.mhtml](iOS 万能跳转界面方法.mhtml)

  • 必备常识

    runtime : 运行时机制 
    首先必须明白的: 
    1.是什么 
    1> runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API 
    2> 平时编写的OC代码, 在程序运行过程中, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者 
    下面这就是一个实例,(在前面的文章中讲到过了!通过编译成c语言,我们可以看到底层文件) 
    OC : 
    [[Person alloc] init] 
    上面的Person对象创建时候, 
    runtime : 
    objc_msgSend(objc_msgSend(“Person” , “alloc”), “init”)
    
    而上面这部分只是明白了最基础的原理,那么runtime又有哪些更深的运用呢? 
    2.runtime用过么?又该怎么用?能用来做什么? 
    我们需要明白的是: 
    1> runtime是属于OC的底层, 可以进行一些非常底层的操作(用OC是无法现实的, 不好实现可以通过runtime是实现)
    
    在程序运行过程中, 动态创建一个类(比如KVO的底层实现)
    在程序运行过程中, 动态地为某个类添加属性\方法, 修改属性值\方法
    遍历一个类的所有成员变量(属性)\所有方法
    3.相关的头文件和函数 
    1> 头文件
    
    
    打开头文件,我们发现许多的方法,但是我们用的最多的是下面的函数, 
    相关函数
    objc_msgSend : 给对象发送消息
    class_copyMethodList : 遍历某个类所有的方法
    class_copyIvarList : 遍历某个类所有的成员变量
    class_…..
    当然,在使用这些东西的时候,我们首先要明白一些东西, 
    必备常识 
    1> Ivar : 成员变量 
    2> Method : 成员方法
    
    2> runtime相关实际应用
    
    NSCoding(归档和解档, 利用runtime遍历模型对象的所有属性)
    字典 –> 模型 (利用runtime遍历模型对象的所有属性, 根据属性名从字典中取出对应的值, 设置到模型的属性上)
    KVO(利用runtime动态产生一个类)
    用于封装框架(想怎么改就怎么改)
    

你可能感兴趣的:(MD)