Search code examples
iosobjective-cpropertiesweak-linking

Can I set the property for a class, which hasn't been specified until run in OC?


I've got a fixed controller with dynamic views as its view. I want to set value for property of a certain view.

Here's code in the controller as below:

@property (nonatomic, retain) Class viewClass;

- (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.view =  _viewClass.new;
        if ([_viewClass resolveInstanceMethod:@selector(lineAdded)]) {
            [_viewClass setValue:@YES forKey:@"lineAdded"];
        }
        self.view.backgroundColor = [UIColor whiteColor];
}

In * the certain* view, I've got a property like this.

@property (nonatomic, assign) BOOL lineAdded;

It reminds me

Undeclared selector 'lineAdded'

When I run, it just skip if condition and go on.

My question is: is it impossible to set property when the class it belongs to isn't specified?

Hope somebody could help me. Thanks in advance.


Solution

  • You can get rid of the warning by making the compiler see a declaration of the lineAdded selector. Either #import a header file that contains a declaration of that property, or declare it another way, for example like this:

    @protocol DummyProtocol
    @property (nonatomic, unsafe_unretained) BOOL lineAdded;
    @end
    

    Second, setting the value of the property doesn't require the lineAdded selector. It requires the setLineAdded: selector.

    Third, the proper way to check whether self.view responds to setLineAdded: is to ask it, like this:

        if ([self.view respondsToSelector:@selector(setLineAdded:)]) {
            [self.view setValue:@YES forKey:@"lineAdded"];
        }
    

    Fourth, you were asking _viewClass whether its instances respond to lineAdded, but then you were asking the _viewClass object itself (rather than the self.view instance of it) to set its own lineAdded property. I fixed that in my code above.

    Fifth, you should assign to self.view in loadView, not in viewDidLoad.

    If, after all that, it's not setting lineAdded, then your view (whatever class you chose) simply doesn't respond to setLineAdded:.