Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 通过类别添加布尔属性_Cocoa_Properties_Categories - Fatal编程技术网

Cocoa 通过类别添加布尔属性

Cocoa 通过类别添加布尔属性,cocoa,properties,categories,Cocoa,Properties,Categories,我正在使用一个categoryNSAttributedString(Additions),我确实需要一种方法来添加一个属性,该属性将是BOOL(指示该字符串是否是HTML标记)。我知道类别不应该有属性,但我需要这样做。我厌倦了写我自己的能手和二传手,但没用。这是如何工作的?类别可以具有只读属性,但不能使用它们添加实例变量(嗯,可以,有点-请参见关联引用) 您可以添加一个category方法(由只读属性表示)isHTMLTag,该方法将返回BOOL,您只需每次在该方法中计算它是否是HTML标记 如

我正在使用一个category
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
作为
对象的参数。