【问题标题】:UILabel category and setFont: crashUILabel 类别和 setFont: 崩溃
【发布时间】:2012-09-18 10:11:58
【问题描述】:

我创建了UILabel 类别,当字体属性更改时会做额外的工作。

我选择了类别而不是子类,因此我不必更改所有 XIB 文件中所有标签的类别。我只是将这个类别声明添加到前缀标题中,类别在整个项目范围内都是可见的。

实现文件:

//
//  UILabel+XIBCustomFonts.m


#import "UILabel+XIBCustomFonts.h"

@implementation UILabel (XIBCustomFonts)
BOOL comes_from_nib = NO;


-(id)initWithCoder:(NSCoder *)aDecoder_{

    self = [super initWithCoder:aDecoder_];

    if (self) {
        comes_from_nib = YES;

    }
    return self;
}

-(void)setFont:(UIFont *)font_{

    [super setFont:font_];
    NSLog(@"Setting from for label from XIB for name:%@ size: %.1f - do font theme replacement if needed", self.font.fontName, self.font.pointSize);

}
@end

令人惊讶的是出现以下日志的崩溃:

-[UIButtonLabel setFont:]: unrecognized selector sent to instance 0x9ad1b70
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIButtonLabel setFont:]: unrecognized selector sent to instance 0x9ad1b70'

UIButtonLabel 是从哪里来的?

即使我在setFont: setter 中进行额外的类检查,也会发生这种情况:

if ([self class] != [UILabel class] || !comes_from_nib) {

        [super setFont:font_];
        return;

    }

有没有什么方法可以覆盖 UILabel 中的 setFont: setter 而不进行子类化?

【问题讨论】:

  • 你从哪个类和方法调用[super setFont:font_];
  • 如源代码所示:它是由类别本身调用的。主要目的是在设置 XIB 网点时获取(字体属性)。
  • 我的意思是你从哪个类或视图控制器调用了这个函数
  • 我从不直接调用它。加载和解码XIB到内存时被系统调用。

标签: iphone ios uilabel categories


【解决方案1】:

你不能在类别中调用超级方法!绝不! 当您使用类别来增强类的功能时,这是不可能的,您没有扩展类,您实际上完全覆盖了现有方法,您完全失去了原始方法。这就是您出现错误的原因。

【讨论】:

  • 我从不从我的代码中调用 UIButtonLabel。看起来它正在被 XIB 解码器调用。关于覆盖 Apple 文档:“当一个类别覆盖一个继承的方法时,该类别中的方法可以像往常一样通过一条消息调用继承的实现。但是,如果一个类别覆盖了一个存在于该类别的类中的方法,无法调用原始实现。”。看起来我没有正确理解引用文档中第一句和第二句之间的区别。
  • 没错,Xib 解码器使用方法 setFont: for object UIButtonLabel,它是 UIButton 的一部分。但主要问题是,对于在该类别中声明的方法,您真的不能调用超类。这就是类别不能完全重叠继承的主要原因。接受吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-08
  • 1970-01-01
  • 2014-03-11
  • 2014-12-15
相关资源
最近更新 更多