iphone - 在 xcode 4.4 中使用类扩展

标签 iphone ios xcode4.4

从 xcode 4.4 开始,您不需要 @synthesize属性不再( see here ),编译器会为您完成。那么,为什么编译器会提示

use of the undeclared identifier _aVar


在我的viewDidLoad ViewControllerSubclass的方法:
@interface ViewController : UIViewController
@property (assign, nonatomic) int aVar;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.aVar = 5;
    NSLog(@"Super value: %d", _aVar);
}
@end

@interface ViewControllerSubclass : ViewController
@end

@interface ViewControllerSubclass ()
@property (assign, nonatomic) int aVar;
@end

@implementation ViewControllerSubclass
- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"Subclass value: %d", _aVar);
}
@end
如果我将所有内容都移动到一个文件而不是 4 个单独的文件用于各自的接口(interface)和实现,编译器反而会提示 _aVar是私有(private)的。但是 _aVar 应该已经在我的 ViewControllerSubclass 中自动合成了。 .
如果我将初始属性声明移至类扩展名,则仍将所有内容保存在 1 个文件中:
@interface ViewController ()
@property (assign, nonatomic) int aVar;
@end
构建仍然失败,说 _aVar是私有(private)的。
如果我回到 4 个文件设置,为相应的接口(interface)和实现 xcode 构建甚至没有警告。
如果我然后运行代码:
[[[ViewControllerSubclass alloc] init] view];
上述示例中的日志语句打印出以下内容:

Super value: 0

Subclass value: 5

NSLog(@"Super value: %d", _aVar); 是有道理的产生 0 的结果因为这个变量应该是父类(super class)私有(private)的。但是,为什么 NSLog(@"Subclass value: %d", _aVar);产生 5 的结果??
这一切都很奇怪。

最佳答案

您混淆了几个不同的问题,当您谈论在文件之间跳转并且您没有指定错误发生的位置时,我有些困惑。

无论如何,存在实例变量可见性的问题。如果您在接口(interface)范围内声明您的 iVar,则默认情况下它们是 protected 。

@interface Foo : NSObject {
    int protectedInt;
@private
    int privateInt;
@public
    int publicInt;
}
@end

当您合成 iVar 时,实例变量本身是私有(private)的,除非您明确指定它们。

方法将始终触发最派生的实现。

现在,当你调用这个...
[[[ViewControllerSubclass alloc] init] view];

您将分配一个子类、初始化并加载 View 。此代码将执行...
@implementation ViewControllerSubclass
- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"Subclass value: %d", _aVar);
}
@end

它做的第一件事是调用基类实现......
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.aVar = 5;
    NSLog(@"Super value: %d", _aVar);
}
@end

当然,它调用 super,但这部分在这里并不重要。下一行将 5 分配给 self.iVar。但是,哪个 iVar?它调用属性 setter 方法在这个物体上。这个实例是什么类型的?这是一个 ViewControllerSubclass .由于您已为基类及其子类指定了相同的名称(并将该属性声明为类扩展的一部分),因此它们每个都有自己的私有(private)范围实例变量。

但是,在最派生的实现上调用了一个方法。因此,self.iVar 将设置子类的实例变量。基类的实例变量保持不变。

当你NSLog该值,您正在访问未更改的基类的私有(private)实例变量。

现在,在基类 viewDidLoad 之后完成后,我们为子类运行代码。它记录其私有(private)实例变量的值,该变量因基类调用属性 setter 而被更改。所以,它现在将打印它的值,即 5。

关于iphone - 在 xcode 4.4 中使用类扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12130125/

相关文章:

iphone tcp/ip 通过附件端口?

iphone - 从 tableView 返回单元格时出错

ios - 从 iPhone 模拟器中删除 Charles SSL 根证书

javascript - 在 Objective-C 中使用 NSPredicate 获取 jQuery 自动完成结果

objective-c - NSArray 的 @[object] 注释

ios - 将 Xcode "deployment target"或 "base SDK"设置为 "point oh one"(0.0.1) 版本

iphone - swift 3 源断开观察者中的 AVPlayer 音频缓冲

ios - 从 iOS SDK 获取 iPhone 联系人时出现问题

ios - 在没有电缆且不使用 TestFlight 的设备上运行 ipa?

objective-c - _objc_retain”,引用自 :__ARCLite__load error in Xcode 4. 4