我正在使用类别NSAttributedString (Additions)
,我真的需要一种方法来添加一个BOOL
的属性(指示字符串是否是HTML标记)。我知道类别不应该有属性,但这就是我需要的方式。我累了写自己的吸气剂和制定者,但它没有用。这怎么可行?
答案 0 :(得分:43)
为了完整起见,我就是这样做的:
@interface
@interface ClassName (CategoryName)
@property (readwrite) BOOL boolProperty;
@end
@implementation
#import <objc/runtime.h>
static char const * const ObjectTagKey = "ObjectTag";
@implementation ClassName (CategoryName)
- (void) setBoolProperty:(BOOL) property
{
NSNumber *number = [NSNumber numberWithBool: property];
objc_setAssociatedObject(self, ObjectTagKey, number , OBJC_ASSOCIATION_RETAIN);
}
- (BOOL) boolProperty
{
NSNumber *number = objc_getAssociatedObject(self, ObjectTagKey);
return [number boolValue];
}
@end
答案 1 :(得分:4)
类别可以具有只读属性,您只是无法使用它们添加实例变量(嗯,您可以,有点 - 参见关联引用)。
您可以添加一个类别方法(由只读属性显示)isHTMLTag
,它将返回BOOL,您只需要计算每次在该方法中它是否为HTML标记。
如果您要求设置 BOOL值的方法,那么您将需要使用我从未使用过的相关引用(objc_setAssociatedObject
),因此感觉不合格更详细地回答。
答案 2 :(得分:1)
我的解决方案不需要对象键,而且更容易阅读语法
<强>的NSString + Helper.h 强>
#import <Foundation/Foundation.h>
@interface NSString (Helper)
@property (nonatomic, assign) BOOL isHTML;
@end
<强>的NSString + Helper.h 强>
#import "NSString+Helper.h"
#import "objc/runtime.h"
@implementation NSString (Helper)
- (void)setIsHTML:(BOOL)isHTML
{
NSNumber *isHTMLBool = [NSNumber numberWithBool:isHTML];
objc_setAssociatedObject(self, @selector(isHTML), isHTMLBool, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isHTML
{
NSNumber *isHTMLBool = objc_getAssociatedObject(self, @selector(isHTML));
return isHTMLBool.boolValue;
}
@end
答案 3 :(得分:0)
如果确实需要添加属性,则应创建子类而不是添加类别。
答案 4 :(得分:0)
在这个世界上可能已经很晚了,当时迅速已经席卷了目标c。无论如何,使用Xcode 8,您还可以使用类属性,而不是使用关联引用。
@interface ClassName (CategoryName)
@property (class) id myProperty;
@end
@implementation
static id *__myProperty = nil;
+ (id)myProperty {
return __myProperty;
}
+ (void)setMyProperty:(id)myProperty {
__myProperty = myProperty;
}
@end
从Xcode 8发行说明:
Objective-C现在支持与之互操作的类属性 Swift类型属性。它们被声明为:@property(class) NSString * someStringProperty;。它们永远不会合成。 (23891898)
答案 5 :(得分:0)
斯威夫特3:
使用此方法,您可以添加任何新属性(此处添加Bool值)到令人兴奋的类。
import ObjectiveC
private var xoAssociationKey: UInt8 = 0
extension <ClassName> {
var <propertyName>: Bool! {
get {
return objc_getAssociatedObject(self, &xoAssociationKey) as? Bool ?? false
}
set(newValue) {
objc_setAssociatedObject(self, &xoAssociationKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
}