setting new properties in category interface/implementation
There is actually a way, which may not be ideal, but does work.
For it to work, you will need to create a category for a class X and can only be used on subclasses of the same X (e.g. category UIView (Background)
can be used with class MyView : UIView
, but not directly with UIView
)
// UIView+Background.h
@interface UIView (Background)
@property (strong, nonatomic) NSString *hexColor;
- (void)someMethodThatUsesHexColor;
@end
// UIView+Background.h
@implementation UIView (Background)
@dynamic hexColor; // Must be declared as dynamic
- (void)someMethodThatUsesHexColor {
NSLog(@"Color %@", self.hexColor);
}
@end
Then
// MyView.m
#import "UIView+Background.h"
@interface MyView : UIView
@property (strong, nonatomic) NSString *hexColor;
@end
@implementation MyView ()
- (void)viewDidLoad {
[super viewDidLoad];
[self setHexColor:@"#BABACA"];
[self someMethodThatUsesHexColor];
}
@end
Using this method, you will need to "redeclare" your properties, but after that, you can do all of its manipulation inside your category.
Checked all answers and did not find the most common solution:
#import <objc/runtime.h>
static void const *key;
@interface ClassName (CategoryName)
@property (nonatomic) BOOL myProperty;
@end
@implementation ClassName (CategoryName)
- (BOOL)myProperty {
return [objc_getAssociatedObject(self, key) boolValue];
}
- (void)setMyProperty:(BOOL)value {
objc_setAssociatedObject(self, key, @(value), OBJC_ASSOCIATION_RETAIN);
}
@end
swift:
private struct AssociatedKeys {
static var keyName = "keyName"
}
extension Foo {
var bar: Any! {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.keyName)
}
set {
objc_setAssociatedObject(self, &AssociatedKeys.keyName , newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
It is not possible to add members and properties to an existing class via a category — only methods.
https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Category.html
One possible workaround is to write "setter/getter-like" methods, that uses a singleton to save the variables, that would had been the member.
-(void)setMember:(MyObject *)someObject
{
NSMutableDictionary *dict = [MySingleton sharedRegistry];
[dict setObject:someObject forKey:self];
}
-(MyObject *)member
{
NSMutableDictionary *dict = [MySingleton sharedRegistry];
return [dict objectforKey:self];
}
or — of course — write a custom class, that inherits from UILabel
Note that nowadays an associated object can be injected during runtime. The Objective C Programming Language: Associative References