Cocoa 通过类别添加布尔属性
我正在使用一个categoryCocoa 通过类别添加布尔属性,cocoa,properties,categories,Cocoa,Properties,Categories,我正在使用一个categoryNSAttributedString(Additions),我确实需要一种方法来添加一个属性,该属性将是BOOL(指示该字符串是否是HTML标记)。我知道类别不应该有属性,但我需要这样做。我厌倦了写我自己的能手和二传手,但没用。这是如何工作的?类别可以具有只读属性,但不能使用它们添加实例变量(嗯,可以,有点-请参见关联引用) 您可以添加一个category方法(由只读属性表示)isHTMLTag,该方法将返回BOOL,您只需每次在该方法中计算它是否是HTML标记 如
NSAttributedString(Additions)
,我确实需要一种方法来添加一个属性,该属性将是BOOL
(指示该字符串是否是HTML标记)。我知道类别不应该有属性,但我需要这样做。我厌倦了写我自己的能手和二传手,但没用。这是如何工作的?类别可以具有只读属性,但不能使用它们添加实例变量(嗯,可以,有点-请参见关联引用)
您可以添加一个category方法(由只读属性表示)isHTMLTag
,该方法将返回BOOL,您只需每次在该方法中计算它是否是HTML标记
如果您想知道设置布尔值的方法,那么您需要使用我从未使用过的关联引用(
objc\u setassociated object
),因此我觉得没有资格回答更多细节 如果您真的需要添加属性,那么您应该创建一个子类,而不是添加一个类别。为了完整起见,我就是这样做的:
@接口
@interface ClassName (CategoryName)
@property (readwrite) BOOL boolProperty;
@end
@实施
#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
#导入
静态字符常量*常量ObjectTagKey=“ObjectTag”;
@实现类名称(CategoryName)
-(void)setBoolProperty:(BOOL)属性
{
NSNumber*number=[NSNumber numberWithBool:属性];
objc_setAssociatedObject(self、ObjectTagKey、number、objc_ASSOCIATION_RETAIN);
}
-(BOOL)boolProperty
{
NSNumber*number=objc_getAssociatedObject(self,ObjectTagKey);
返回[数字布尔值];
}
@结束
我的解决方案不需要对象键,语法更易于阅读
NSString+Helper.h
#import <Foundation/Foundation.h>
@interface NSString (Helper)
@property (nonatomic, assign) BOOL isHTML;
@end
#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
也许在这个世界上很晚的时候,斯威夫特已经横扫了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;
}
@结束
从Xcode 8发行说明中:
Objective-C现在支持类属性,这些属性与
Swift类型属性。它们被声明为:@property(class)
NSString*someStringProperty;。它们从未被合成过。(23891898)
Swift 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)
}
}
}
导入ObjectiveC
私有变量xoAssociationKey:UInt8=0
延伸{
瓦尔:呸{
得到{
将objc_getAssociatedObject(self,&xAssociationKey)返回为?Bool??false
}
设置(新值){
objc_setAssociatedObject(self,&xoAssociationKey,newValue,objc_AssociationPolicy.objc_ASSOCIATION_RETAIN)
}
}
}
为您的getter和setter发布代码!使用关联的引用成功了!谢谢你介意分享一下你是如何做到这一点的吗?@Mace-你能接受jrturton的答案,并从Joshua那里添加细节,还是接受Joshua的答案…?有时候这是不可能的。例如,如果创建所述类实例的代码不可访问(例如,在静态库中),那么内存管理呢?NSNumber实例由self在-setBoolProperty:方法中保留。我需要释放它吗?从runtime.h:“@param value与对象的键关联的值。传递nil以清除现有的关联。”但我不能覆盖类别中的dealloc。在这里找到了一个答案:它被正确地释放,通过这种方式,您可以省略对键使用额外常量;相反,只需使用@selector(boolProperty)而不是ObjectTagKey,它将提供您想要的内容need@igrek这不适用于类别。类别不允许使用@selector()代替静态字符常量*
您可以使用静态int-ObjectTagKey
并使用&ObjectTagKey
作为对象的参数。