Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setting new properties in category interface/implementation

Ok, so I have this, but it wont work:

@interface UILabel (touches)

@property (nonatomic) BOOL isMethodStep;

@end


@implementation UILabel (touches)

-(BOOL)isMethodStep {
    return self.isMethodStep;
}

-(void)setIsMethodStep:(BOOL)boolean {
    self.isMethodStep = boolean;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if(self.isMethodStep){
        // set all labels to normal font:
        UIFont *toSet = (self.font == [UIFont fontWithName:@"Helvetica" size:16]) ? [UIFont fontWithName:@"Helvetica-Bold" size:16] : [UIFont fontWithName:@"Helvetica" size:16];

        id superView = self.superview;
        for(id theView in [(UIView *)superView subviews])
            if([theView isKindOfClass:[UILabel class]])
                [(UILabel *)theView setFont:[UIFont fontWithName:@"Helvetica" size:16]];

        self.font = toSet;
    }
}

@end

If I take out the getter and setter methods then it doesn't work it tells me I need to create some getter and setter methods (or use @synthesize - but putting @synthesize in the @implementation throws an error too). But with the getter and setter methods I get an EXC_BAD_ACCESS and a crash. Any ideas? Thanks

Tom

like image 820
Thomas Clayson Avatar asked Nov 04 '10 16:11

Thomas Clayson


People also ask

Can an interface have a default implementation for a property?

Beginning with C# 8.0, an interface may define a default implementation for members, including properties. Defining a default implementation for a property in an interface is rare because interfaces may not define instance data fields.

How do you declare an interface property?

Interface Properties (C# Programming Guide) Properties can be declared on an interface. The following is an example of an interface property accessor: public interface ISampleInterface { // Property declaration: string Name { get; set; } } The accessor of an interface property does not have a body.

What is interface property accessor?

Interface Properties (C# Programming Guide) Properties can be declared on an interface. The following is an example of an interface property accessor: The accessor of an interface property does not have a body.

What is implemented interfaces?

Implementing interfaces is based on the concept of object-oriented programming. With common interfaces, you can use different but similar function blocks the same way. A function block that implements an interface has to include all methods and attributes that are defined in that interface (interface methods and interface attributes).


2 Answers

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

like image 185
vikingosegundo Avatar answered Oct 17 '22 15:10

vikingosegundo


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)
        }
    }
}
like image 20
Kirow Avatar answered Oct 17 '22 14:10

Kirow