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

好吧,所以我有这个,但它不会工作:

@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方法,那么它不起作用,它告诉我,我需要创build一些getter和setter方法(或使用@synthesize – 但@implementation中@synthesize也会引发错误)。 但是通过getter和setter方法,我得到了一个EXC_BAD_ACCESS和一个崩溃。 有任何想法吗? 谢谢

汤姆

无法通过类别方法将成员和属性添加到现有类中。

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

一种可能的解决方法是编写“setter / getter-like”方法,它使用单例保存variables,这将是成员。

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

或者 – 当然 – 写一个从UILabelinheritance的自定义类


请注意,现在可以在运行时注入一个关联的对象 。 Objective C编程语言:关联引用

检查了所有的答案,没有find最常见的解决scheme:

 #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 

实际上有一种办法,这可能不是理想的,但工作。
对于它的工作,你将需要为类X创build一个类别,只能用于相同的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 

使用这种方法,您需要“重新声明”您的属性,但在此之后,您可以在类别中进行所有操作。

编辑:警告:此属性将具有该类的所有实例的唯一值。

这工作对我来说,但只是因为我在我的应用程序中只有一个这个类的实例。

 #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 

我发现这个解决scheme只是给每个你想要标记的对象一个独特的标签。

我做了一个UILabel类别添加自定义字体到我的所有标签,但在一些我想他们是大胆的,所以我做到了这一点 – >

 - (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]]; } } 

看起来好像从Xcode 7 (7.0.1,7A1001),属性在类别中被支持。 我注意到Xcode现在为Core Data子类生成类别。

例如,我得到的文件:

位置+ 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 

所以看起来像属性类别可能现在工作。 我还没有在非核心数据类上进行testing。

我注意到,他们确实把类别文件包括回原来的类中:

Location.h

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

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