Forward Declaration vs #import when subclassing
I have MyClassA
which has a property of type MyClassB
//
// MyClassA.h
//
@interface MyClassA : NSObject
@property (strong, nonatomic, readonly) MyClassB *myClassB;
@end
MyClassB
has a property myString
.
//
// MyClassB.h
//
@interface MyClassB : NSObject
@property (copy, nonatomic, readonly) NSString *myString;
@end
I have MyClassC
which needs to access myString
in it's implementation.
Should I -
a) Forward Declare MyClassB
in MyClassA.h
and #import "MyClassB.h"
in MyClassC.m
or
b) #import MyClassB.h
in MyClassA.h
In general, you should forward declare with @class
where possible in your header files. The only time you probably wouldn't want to do it is when you're inheriting from a super class or declaring protocol conformance, because the compiler needs to know what is going on in that class or protocol.
For this instance, I would use @class for all your property declarations in your header files, and #import MyClassB.h
in your MyClassC.m file. That will allow MyClassC to know about all the properties on MyClassB.
Looking at this from a slightly different angle ... you need to decide if you want the world to really know about myClassB
being a property of MyClassA
. For example, if you may only want to advertise that myString
that can be obtained through MyClassA
. This insulates other classes from knowing the underlying implementation of myString
. Unless you have a need to expose MyClassB
you should hide it from the "rest of the world".
In this case you would change MyClassA.h as follows:
//
// MyClassA.h
//
@interface MyClassA : NSObject
@property (strong, nonatomic, readonly) NSString *myString;
@end
In MyClassA.m, you would do the following.
//
// MyClassA.m
//
#import "MyClassA.h"
#import "MyClassB.h"
@interface MyClassA()
@property (strong, nonatomic) MyClassB *myClassB;;
@end
@implementation MyClassA
// Other meaningful code omitted
- (NSString *)myString {
return self.myClassB.myString;
}
@end
Note that what I've done here is use an anonymous category to internally define property for myClassB
.
The key thing here is whether or not it makes sense to not expose MyClassB
to others. The main advantage of this approach is your code is more malleable. Let's say myString
gets derived a different way. From a different class or different method altogether. The code which needs to consume myString
is immunized.
If you need to expose MyClassB
, then you can either use @class
as recommended by Tyler above or #import MyClassB.h
from MyClassA.h. Best practices prescribe forward declaring @class
. But at times the convenience of not having to remember to import a lot of files within the implementation file can win out. It's your code-base, so you can pick which one works the best for you. I generally use a combination of the two.
上一篇: 在多个网络应用和服务之间共享AI密钥?
下一篇: 前向声明与#import的子类化