Search code examples
iosobjective-cuitextviewnsattributedstringobjective-c-category

performSelector in category of superclass fails when calling method available in specific subclass


I have UIView category that defines methods to manipulate attributedText property of UILabel and UITextView.

@implementation UIView (replaceAttrText)
-(void) replaceAttrText: (NSString *)str {
    if ([self respondsToSelector: @selector(setAttributedText)]) {
        NSMutableAttributedString *labelText = [self template];

        // change it

        [self performSelector:@selector(setAttributedText) withObject: labelText];
    }
}
@end

respondsToSelector returns false for both UILabel and UITextView (although they respond to setAttributedText) and if setAttributedText is executed directly without respondsToSelector check an exception is raised.

When category is implemented directly on UILabel (without selectors) everything works, but unfortunately UILabel and UITextView don't have common ancestor that has attributedText property.

What am I doing wrong? Thanks!


Solution

  • UILabel and UITextView do not have a method named setAttributedText. But they do have a method named setAttributedText:. Note the colon. The colon is part of the method name. Having it or not represents two completely separate methods.

    Change your code to:

    -(void) replaceAttrText: (NSString *)str {
        if ([self respondsToSelector: @selector(setAttributedText:)]) {
            NSMutableAttributedString *labelText = [self template];
    
            // change it
    
            [self performSelector:@selector(setAttributedText:) withObject: labelText];
        }
    }
    

    In other words, add a colon to both references to setAttributedText.