2012-03-19 81 views
16

我正在使用一个类别NSAttributedString(Additions),我真的需要一种方法来添加一个属性,如果该字符串是HTML标记,将会成为BOOL。我知道类别不应该有属性,但这是我需要这样做的方式。我厌倦了写自己的getters和setter,但它不起作用。任何人都知道这将如何工作?如何将BOOL属性添加到类别?

+0

[Objective-C:Property in Category](http:// stackoverflow。com/questions/8733104/objective-c-property-in-category) – 2012-03-20 01:28:08

+0

发布你的getters和setter的代码! – paulmelnikow 2012-03-20 20:28:09

回答

4

类别可以具有只读属性,但不能将实例变量与它们一起添加(嗯,可以,有点 - 请参阅关联参考)。

您可以添加一个类别方法(由只读属性提供)isHTMLTag这将返回一个布尔值,您将只需要计算它是否是每次在该方法中的HTML标记。

如果你问一种方式来设置的BOOL值,那么你需要使用哪个我从来没有用过所以不觉得有资格以任何更详细的回答对相关引用(objc_setAssociatedObject)。

+1

使用关联的引用起作用!谢谢 – Mace 2012-04-18 19:20:55

+0

你介意分享你的工作方式吗? – 2012-07-14 19:52:03

+3

@Mace--你能接受jrturton的答案,并加入Joshua的细节,或接受Joshua的答案......? – 2013-03-26 10:36:45

0

如果你真的需要添加一个属性,那么你应该创建一个子类而不是添加一个类别。

+1

有时候这是不可能的。例如,如果创建所述类实例的代码不可访问(例如,在静态库中)。 – 2012-10-04 10:30:06

38

为了完整起见,我这是怎么得到这个工作:

@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 
+0

内存管理如何? NSNumber实例由self保存在-setBoolProperty:方法中。我需要以某种方式释放它吗?从runtime.h:“@param value与对象的关键键关联的值。通过nil清除现有关联。”但我不能在一个类别中覆盖dealloc。 – igrek 2014-08-13 14:21:47

+0

在这里找到了答案:http://stackoverflow.com/questions/10842829/will-an-associated-object-be-released-automatically/10843510#10843510它被正确释放 – igrek 2014-08-13 14:28:32

+0

顺便说一句,你可以省略使用额外的常量为钥匙;相反,只需使用@selector(boolProperty)而不是ObjectTagKey,它将提供您所需的 – igrek 2014-08-13 14:29:44

0

我的解决方案,而不需要一个对象键并且稍微容易阅读语法

NSString + Help er.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 
0

也许在这个世界上得很晚,迅速在已经席卷Objective 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的现在支持类的属性,这与 夫特型特性互操作。它们被声明为:@property(class) NSString * someStringProperty ;.他们从未合成过。 (23891898)

0

斯威夫特3:

使用这种方法,您可以添加任何新的财产(这里补充布尔值)的精彩类。

import ObjectiveC 

private var xoAssociationKey: UInt8 = 0 

extension <ClassName> { 
    var <propertyName>: Bool! { 
     get { 
      if let returnVal = objc_getAssociatedObject(self, &xoAssociationKey) as? Bool{ 
       return returnVal 
      }else{ 
       return false 
      } 

     } 
     set(newValue) { 

      objc_setAssociatedObject(self, &xoAssociationKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) 
     } 
    } 
}