I am using a category NSAttributedString (Additions)
and I really need a way to add a property that will be a BOOL
(indicating whether the string is an HTML tag or not). I know that categories should not have properties but that's the the way I need to do it. I tired writing my own getters and setters but it didn't work. How can this work?
-
1Post the code for your getters and setters! – paulmelnikow Mar 20 '12 at 20:28
6 Answers
For the sake of completeness, this is how I got this to work:
@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,714
- 1
- 17
- 36
-
What about memory management? The NSNumber instance is retained by self within the -setBoolProperty: method. Do i need to release it somehow? From runtime.h: "@param value The value to associate with the key key for object. Pass nil to clear an existing association." But i can't override dealloc in a category. – igrek Aug 13 '14 at 14:21
-
Found an answer here: http://stackoverflow.com/questions/10842829/will-an-associated-object-be-released-automatically/10843510#10843510 It is released properly – igrek Aug 13 '14 at 14:28
-
By the way, you can omit using extra constants for Keys; instead, just use @selector(boolProperty) instead of the ObjectTagKey, which will provide exactly what you need – igrek Aug 13 '14 at 14:29
-
@igrek that's not working with categories. Categories don't allow @selector() – d.ennis Dec 22 '14 at 12:24
-
Instead of a `static char const*` you can use `static int ObjectTagKey` and use `&ObjectTagKey` as parameter for `objc_...` – Eun Jan 22 '15 at 14:28
-
I believe that @iHS has the best up-to-date answer. https://stackoverflow.com/a/46920788/5494489 – CJ Dev Oct 23 '19 at 19:18
Categories can have read-only properties, you just can't add instance variables with them (well, you can, sort of - see associative references).
You can add a category method (presented by a read only property) isHTMLTag
which would return a BOOL, you would just have to calculate if it was an HTML tag each time within that method.
If you are asking for a way to set the BOOL value then you'll need to use associated references (objc_setAssociatedObject
) which I've never used so don't feel qualified to answer on in any more detail.

- 118,105
- 32
- 252
- 268
-
1
-
-
3@Mace — can you accept either jrturton's answer, and add the details from Joshua, or accept Joshua's answer...? – Kaolin Fire Mar 26 '13 at 10:36
My solution without the need of an object key and a little bit easier to read syntax
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

- 376
- 5
- 9
Probably very late in this world, when swift is already sweeping objective c. Anyhow, with Xcode 8, you can also use class properties, instead of using associative references.
@interface ClassName (CategoryName)
@property (class) id myProperty;
@end
@implementation
static id *__myProperty = nil;
+ (id)myProperty {
return __myProperty;
}
+ (void)setMyProperty:(id)myProperty {
__myProperty = myProperty;
}
@end
From the Xcode 8 release notes:
Objective-C now supports class properties, which interoperate with Swift type properties. They are declared as: @property (class) NSString *someStringProperty;. They are never synthesized. (23891898)

- 5,372
- 4
- 31
- 49
Swift 3:
Using this method, you can add any new property (here add Bool value) to the exciting class.
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)
}
}
}

- 9,916
- 5
- 46
- 54

- 478
- 4
- 15
If you really need to add a property, then you should create a subclass instead of adding a category.

- 25,760
- 8
- 60
- 101
-
1Sometimes that's not possible. For example, if the code that creates the instance of said class is not accessible (e.g. in a static library). – Ben Clayton Oct 04 '12 at 10:30