代码之家  ›  专栏  ›  技术社区  ›  Thomas Clayson

在类别接口/实现中设置新属性

  •  14
  • Thomas Clayson  · 技术社区  · 14 年前

    好吧,我有这个,但不行:

    @interface UILabel (touches)
    
    @property (nonatomic) BOOL isMethodStep;
    
    @end
    
    
    @implementation UILabel (touches)
    
    -(BOOL)isMethodStep {
        return self.isMethodStep;
    }
    
    -(void)setIsMethodStep:(BOOL)boolean {
        self.isMethodStep = boolean;
    }
    
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        if(self.isMethodStep){
            // set all labels to normal font:
            UIFont *toSet = (self.font == [UIFont fontWithName:@"Helvetica" size:16]) ? [UIFont fontWithName:@"Helvetica-Bold" size:16] : [UIFont fontWithName:@"Helvetica" size:16];
    
            id superView = self.superview;
            for(id theView in [(UIView *)superView subviews])
                if([theView isKindOfClass:[UILabel class]])
                    [(UILabel *)theView setFont:[UIFont fontWithName:@"Helvetica" size:16]];
    
            self.font = toSet;
        }
    }
    
    @end
    

    如果我去掉getter和setter方法,那么它就不起作用了,它告诉我需要创建一些getter和setter方法(或者使用@synthey-但是把@synthey放在@implementation中也会抛出一个错误)。但是使用getter和setter方法,我会得到一个EXC_BAD_ACCESS和一个崩溃。有什么想法吗?谢谢

    汤姆

    7 回复  |  直到 12 年前
        1
  •  39
  •   Cœur N0mi    7 年前

    不可能通过只使用类别的方法将成员和属性添加到现有的类中。

    https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Category.html

    一种可能的解决方法是编写“setter/getter-like”方法,该方法使用一个单例来保存变量,该变量本来就是成员。

    -(void)setMember:(MyObject *)someObject
    {
        NSMutableDictionary *dict = [MySingleton sharedRegistry];
        [dict setObject:someObject forKey:self];
    }
    
    -(MyObject *)member
    {
        NSMutableDictionary *dict = [MySingleton sharedRegistry];
        return [dict objectforKey:self];
    }
    

    或者编写一个自定义类,继承自UILabel


    注意现在 可以在运行时注入。 The Objective C Programming Language: Associative References

        2
  •  4
  •   Kirow    5 年前

    #import <objc/runtime.h>
    
    static void const *key;
    
    @interface ClassName (CategoryName)
    @property (nonatomic) BOOL myProperty;
    @end
    
    @implementation ClassName (CategoryName)
    - (BOOL)myProperty {
        return [objc_getAssociatedObject(self, key) boolValue];
    }
    
    - (void)setMyProperty:(BOOL)value {
        objc_setAssociatedObject(self, key, @(value), OBJC_ASSOCIATION_RETAIN);
    }
    @end
    

    银行代码:

    private struct AssociatedKeys {
        static var keyName = "keyName"
    }
    
    extension Foo {
        var bar: Any! {
            get {
                return objc_getAssociatedObject(self, &AssociatedKeys.keyName)
            }
            set {
                objc_setAssociatedObject(self, &AssociatedKeys.keyName , newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
    }
    
        3
  •  1
  •   Guilherme    9 年前


    要使其工作,您需要为类X创建一个类别,并且只能在 子类 UIView (Background) 可与类一起使用 MyView : UIView UIView )

    // UIView+Background.h
    
    @interface UIView (Background)
    
    @property (strong, nonatomic) NSString *hexColor;
    
    - (void)someMethodThatUsesHexColor;
    
    @end
    
    // UIView+Background.h
    
    @implementation UIView (Background)
    
    @dynamic hexColor; // Must be declared as dynamic
    
    - (void)someMethodThatUsesHexColor {
        NSLog(@"Color %@", self.hexColor);
    }
    
    @end
    

    那么

    // MyView.m
    
    #import "UIView+Background.h"
    
    @interface MyView : UIView
    
    @property (strong, nonatomic) NSString *hexColor;
    
    @end
    
    @implementation MyView ()
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self setHexColor:@"#BABACA"];
        [self someMethodThatUsesHexColor];
    }
    
    @end
    

        4
  •  1
  •   Lal Krishna    6 年前

    您可以在运行时插入关联的对象。

    #import <objc/runtime.h>
    
    @interface UIView (Private)
    
    @property (nonatomic, assign) CGPoint initialTouchPoint;
    @property (nonatomic, strong) UIWindow *alertWindow;
    
    @end
    
    @implementation UIView (Private)
    
    @dynamic initialTouchPoint, alertWindow;
    
    - (CGPoint)initialTouchPoint {
        return CGPointFromString(objc_getAssociatedObject(self, @selector(initialTouchPoint)));
    }
    
    - (void)setInitialTouchPoint:(CGPoint)initialTouchPoint {
        objc_setAssociatedObject(self, @selector(initialTouchPoint), NSStringFromCGPoint(initialTouchPoint), OBJC_ASSOCIATION_RETAIN);
    }
    
    - (void)setAlertWindow:(UIWindow *)alertWindow {
        objc_setAssociatedObject(self, @selector(alertWindow), alertWindow, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (UIWindow *)alertWindow {
        return objc_getAssociatedObject(self, @selector(alertWindow));
    }
    
    @end
    
        5
  •  0
  •   Maxim Chetrusca    11 年前

    编辑:警告:此属性对于类的所有实例都具有唯一的值。

    这对我有效,但只是因为我的应用程序中只有一个此类实例。

    #import <AVFoundation/AVFoundation.h>
    
    @interface AVAudioPlayer (AstroAVAudioPlayer)
    
    @property (nonatomic) BOOL redPilot;
    
    @end
    
    
    #import "AVAudioPlayer+AstroAVAudioPlayer.h"
    
    @implementation AVAudioPlayer (AstroAVAudioPlayer)
    
    BOOL _redPilot;
    
    -(void) setRedPilot:(BOOL)redPilot
    {
        _redPilot = redPilot;
    }
    
    -(BOOL) redPilot
    {
        return _redPilot;
    }
    
    @end
    
        6
  •  0
  •   shokaveli    10 年前

    我发现一个解决方案就是给每个你想要标记的对象一个唯一的标签。

    - (void) layoutSubviews {
        [super layoutSubviews];
        [self addCustomFont];   
    }
    
    - (void) addCustomFont {
        if (self.tag == 22) {
            [self setFont:[UIFont fontWithName:SEGOE_BOLD size:self.font.pointSize]];
        }else{
            [self setFont:[UIFont fontWithName:SEGOE_LIGHT size:self.font.pointSize]];
        }
    }
    
        7
  •  0
  •   mikeho    9 年前

    好像是因为 代码7 (7.0.1,7A1001),属性按类别支持。我注意到 Xcode码 子类。

    例如,我得到了文件:

    位置+CoreDataProperties.h

    #import "Location.h"
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface Location (CoreDataProperties)
    
    @property (nullable, nonatomic, retain) NSNumber *altitude;
    @property (nullable, nonatomic, retain) NSNumber *latitude;
    @property (nullable, nonatomic, retain) NSNumber *longitude;
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    位置+CoreDataProperties.m

    #import "Location+CoreDataProperties.h"
    
    @implementation Location (CoreDataProperties)
    
    @dynamic altitude;
    @dynamic latitude;
    @dynamic longitude;
    
    @end
    

    所以看起来分类中的属性现在可以工作了。我没有做过非- 上课。

    我注意到的是,它们确实将类别文件包含回原始类中:

    位置h

    @interface Location : NSManagedObject
    
    @end
    
    #import "Location+CoreDataProperties.h"
    

    这允许原始类编辑类别指定的属性。