2012-03-19 82 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) 
     } 
    } 
}