• layoutSubviews、drawRect、initialize和load方法的调用


      - (void)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实时刷新屏幕

      +(void)load,是加载类的时候就会调用。也就是说,ios应用启动的时候,就会加载所有的类,就会调用这个方法。

       这样有个缺点,当加载类需要很昂贵的资源,或者比较耗时的时候,可能造成不良的用户体验,或者系统的抖动。这时候,就要考虑initialize方法了。这个方法可看作类加载的延时加载方法。类加载后并不执行该方法。只有当实例化该类的实例的时候,才会在第一个实例加载前执行该方法。

       +(void)load在Objective-C运行时载入类或者Category时被调用,这个方法对动态库和静态库中的类或(Category)都有效.

     

      另外

      * 一个类的+load方法在其父类的+load方法后调用

      * 一个Category的+load方法在被其扩展的类的自有+load方法后调用

      在+load方法中,可以安全地向同一二进制包中的其它无关的类发送消息,但接收消息的类中的+load方法可能尚未被调用。

     

      注意:

      1、initialize和load,我们并不需要在这两个方法的实现中使用super调用父类的方法。

      2、load和initialize被调用一次是相对runtime而言 ,你可以当作普通类方法多次调用。

      3、类加载到系统的时候就用调用load方法,类首次使用的时候调用initialize方法。

      4、load不像普通方法一样遵从那套继承规则,当每个类没有实现 load方法,不管各级超类是否实现,系统都不会调用此类的load方法。initialize与其他方法一样,如果每个类没有实现initialize方法,而超类实现了,那么就会执行超类的这个方法,

      5、initialize和load的方法必须写的精简。

      6、initialize中可以实现无法在编译期初始化的全局变量,load的方法中可以实现swizzling的逻辑。

      7、load的调用并不视为类的第一个方法完成,因为load中调用了当前类中的方法,就先去执行initialize方法了。

      8、Runtime调用+(void)load时没有autorelease pool,

      9、load方法调用的顺序:父类(Superclass)的方法优先于子类(Subclass)的方法,类中的方法优先于类别(Category)中的方法。

      10、所有类别(Category)中的load方法都会执行。

      11、最后一个类别(Category)中的initialize方法会覆盖之前类别和类中的initialize方法。

  • 相关阅读:
    正则表达式大全
    函数基础(二)
    函数基础(一)
    bzoj3531 [Sdoi2014]旅行
    bzoj4785 [Zjoi2017]树状数组
    bzoj4568 [Scoi2016]幸运数字
    bzoj1975 [Sdoi2010]魔法猪学院
    bzoj1079 [SCOI2008]着色方案
    bzoj1996 [Hnoi2010]chorus 合唱队
    bzoj2326 [HNOI2011]数学作业
  • 原文地址:https://www.cnblogs.com/ljios/p/4911033.html
Copyright © 2020-2023  润新知