Ben*_*ard 13 inheritance cocoa gcc objective-c gcc4
更新 - 许多人坚持要我为该物业申报iVar.有些人说不是这样,因为我正在使用Modern Runtime(64位).我可以确认我已经成功使用@property而没有iVars几个月了.因此,我认为'正确'的答案是解释为什么在64位上我突然必须明确声明iVar何时(并且仅当)我将从子类访问它.到目前为止,我见过的唯一一个可能是GCC错误(感谢Yuji).毕竟不是那么简单......为了澄清可能的错误:当从基类继承时,子进程无法访问父进程的iVar,并且在访问iVar之前,该子进程也恰好使用@synthesize实现了一个UNRELATED访问器.
我一直在摸不着头几个小时 - 我没有太多使用遗产.
在这里,我设置了一个简单的Test B类,它继承自Test A,其中声明了一个ivar.但是我得到了变量未声明的编译错误.这只发生在我添加属性和合成声明时 - 没有它们就可以正常工作.
TestA标题:
#import <Cocoa/Cocoa.h>
@interface TestA : NSObject {
NSString *testString;
}
@end
Run Code Online (Sandbox Code Playgroud)
TestA实现为空:
#import "TestA.h"
@implementation TestA
@end
Run Code Online (Sandbox Code Playgroud)
TestB标题:
#import <Cocoa/Cocoa.h>
#import "TestA.h"
@interface TestB : TestA {
}
@property (nonatomic, retain) NSString *testProp;
@end
Run Code Online (Sandbox Code Playgroud)
TestB实现(错误 - 'testString'未声明)
#import "TestB.h"
@implementation TestB
@synthesize testProp;
- (void)testing{
NSLog(@"test ivar is %@", testString);
}
@end
Run Code Online (Sandbox Code Playgroud)
Yuj*_*uji 10
我认为这是GCC 4.2.1的错误.我用foo.m内容制作了文件
#import <Foundation/Foundation.h>
@interface TestA : NSObject {
NSString *testString;
}
@end
@implementation TestA
@end
@interface TestB : TestA {
}
@property (retain) NSString *testProp;
@end
@implementation TestB
@synthesize testProp;
- (void)testing{
NSLog(@"test ivar is %@", testString);
}
@end
Run Code Online (Sandbox Code Playgroud)
请注意,在64位模式下可以省略实例变量.OS X 10.6.3上的我的GCC 4.2.1给了我一个错误:
$ gcc -arch x86_64 -c foo.m
aho.m: In function ‘-[TestB testing]’:
aho.m:19: error: ‘testString’ undeclared (first use in this function)
aho.m:19: error: (Each undeclared identifier is reported only once
aho.m:19: error: for each function it appears in.)
Run Code Online (Sandbox Code Playgroud)
通过更改编译没有问题
NSLog(@"test ivar is %@", testString);
Run Code Online (Sandbox Code Playgroud)
至
NSLog(@"test ivar is %@", self->testString);
Run Code Online (Sandbox Code Playgroud)
Clang编译它没有任何问题.
(在32位模式下,我得到了
$ gcc -arch i386 -c foo.m
aho.m:17: error: synthesized property ‘testProp’ must either be named
the same as a compatible ivar or must explicitly name an ivar
aho.m: In function ‘-[TestB testing]’:
aho.m:19: error: ‘testString’ undeclared (first use in this function)
aho.m:19: error: (Each undeclared identifier is reported only once
aho.m:19: error: for each function it appears in.)
Run Code Online (Sandbox Code Playgroud)
正如Manjunath写的那样,这是一种完全预期的行为.)
但是我认为访问超类的实例变量通常是一个相当不错的主意:当你实现超类的方法时,你不能假设任何关于实例变量的东西,因为它可能会以最坏的方式被子类调整.您至少需要写下允许或不允许对实例变量执行何种操作...请记住,您可能需要多年维护代码!我更希望在方法和属性级别保持代码的各个部分之间的编程契约.
最后你应该改变
@property NSString *testProp;
Run Code Online (Sandbox Code Playgroud)
至
@property (copy) NSString *testProp;
Run Code Online (Sandbox Code Playgroud)
或至少到
@property (retain) NSString *testProp;
Run Code Online (Sandbox Code Playgroud)
如果您在OS X上没有使用GC,否则EXP_BAD_ACCESS将等待您的到来!
| 归档时间: |
|
| 查看次数: |
4010 次 |
| 最近记录: |