您的位置:首页 > 其它

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

2015-10-26 14:04 176 查看
  - (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方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: