简体   繁体   中英

Redeclared property not recognized with redeclared type for the getter

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:

  1. Can anyone explain to me why the foo getter is not using the redeclared type when accessed in the implementation?

  2. 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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM