Reputation: 79
I'm running into a problem when I'm redeclaring a property (readonly->readwrite attribute, and protocol->concrete type). When using the getter in the implementation, I expected the getter to have the redeclared type, but instead it kept the original type.
See Example:
Foo.h
#import <Foundation/Foundation.h>
@protocol FooProtocol <NSObject>
@property (nonatomic) id someProperty;
@end
@interface Foo : NSObject <FooProtocol>
@property (nonatomic) id additionalProperty;
@end
Foo.m
#import "Foo.h"
@implementation Foo
@end
Test.h
#import <Foundation/Foundation.h>
#import "Foo.h"
@interface Test : NSObject
@property (nonatomic, readonly) id<FooProtocol> foo;
@end
Test.m
#import "Test.h"
@interface Test ()
@property (nonatomic) Foo *foo;
@end
@implementation Test
- (void)testMethod {
self.foo.additionalProperty; // Error here: Property 'additionalProperty' not found on object of type 'id<FooProtocol>'
}
@end
With all that said I have two questions:
Can anyone explain to me why the foo getter is not using the redeclared type when accessed in the implementation?
Are there any good solutions / work arounds without:
A. modifying the interface in Test.h (I don't want to expose more, or make the interface more complicated)
B. casting the results of the foo getter whenever I use it (not very clean code)
Any help is greatly appreciated, thanks!
I did come up with one possible work around by declaring a 2nd property instead of redeclaring the original property, but I don't think it's the cleanest, and could definitely make the code more confusing to read:
Test.m (with workaround):
#import "Test.h"
@interface Test ()
@property (nonatomic) Foo *foo2;
@end
@implementation Test
- (id<FooProtocol>)foo {
return self.foo2;
}
- (void)testMethod {
self.foo2.additionalProperty // No error
}
@end
Upvotes: 0
Views: 54
Reputation: 53000
Ugly (but beauty is in the eye of the beholder), but it does quieten the compiler:
- (void)testMethod
{
... _foo.additionalProperty ...;
}
This just bypasses the getter for foo
and reads the backing variable directly.
Logically the compiler shouldn't object to your code, but then there is no formal definition of Objective-C so it can't be said to be in violation of it! However you might wish to submit a report to bugreport.apple.com
Upvotes: 1