【问题标题】:Extracting a common superclass from two UIApplicationDelegate implementations leads to a crash when trying to set the window outlet尝试设置窗口出口时,从两个 UIApplicationDelegate 实现中提取公共超类会导致崩溃
【发布时间】:2013-10-08 22:18:17
【问题描述】:

我们有一个项目构建两个独立的目标,这些目标具有实现UIApplicationDelegate 的特定于目标的类。从两个特定于应用程序的应用程序委托中提取超类后,我们发现应用程序在启动时崩溃,并出现错误,通常表明连接的IBOutlet 没有有效的实现:

[...YYYAppDelegate... setValue:forUndefinedKey:]: 这个类不是键 键窗口的值编码兼容。

堆栈跟踪和崩溃时间是这个问题的典型特征 - 显然,我们所做的事情破坏了 window 属性。

在执行重构之前,我们的应用委托接口和实现如下所示:

@interface YYYAppDelegate : NSObject <UIApplicationDelegate>
...
@property (nonatomic, strong) IBOutlet UIWindow *window;
...
@end

@implementation YYYAppDelegate

// No @synthesize of window
...
@end

@interface ZZZAppDelegate : NSObject <UIApplicationDelegate>
...
@property (nonatomic, strong) IBOutlet UIWindow *window;
...
@end

@implementation ZZZAppDelegate

// No @synthesize of window
...
@end

window 属性是自动合成的,因为我们在每个类的 @interface 块中从 UIApplicationDelegate 重新声明了 window 属性。

重构之后的样子是这样的:

@interface XXXAppDelegate : NSObject <UIApplicationDelegate>
...
@end

@implementation XXXAppDelegate
...
@end

@interface YYYAppDelegate : XXXAppDelegate
...
@property (nonatomic, strong) IBOutlet UIWindow *window;
...
@end

@implementation YYYAppDelegate
// No @synthesize of window
...
@end

@interface ZZZAppDelegate : XXXAppDelegate
...
@property (nonatomic, strong) IBOutlet UIWindow *window;
...
@end

@implementation ZZZAppDelegate
// No @synthesize of window
...
@end

这里发生了什么?为什么以这种方式提取超类会破坏window 属性?

【问题讨论】:

    标签: ios objective-c uiapplicationdelegate


    【解决方案1】:

    属性自动合成不会自动合成在协议中声明的属性 - 必须在类的 @interface 中重新声明它们或添加显式 @synthesize。但是,在继承自声明符合此协议的类的类的@interface 中重新声明协议属性不会导致自动合成该属性。我找不到关于这一点的官方声明,但该行为在多次测试中似乎是一致的。

    必须在声明符合协议的基类中重新声明属性,或者在超类或每个子类中添加@synthesize 语句。在我们的例子中,我们通过向XXXAppDelegate 添加显式合成来解决它,如下所示:

    @interface XXXAppDelegate : NSObject <UIApplicationDelegate>
    ...
    @end
    
    @implementation XXXAppDelegate
    
    @synthesize window;
    
    @end
    

    为了整洁,我们还删除了子类中的属性重新声明。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      • 2022-08-23
      相关资源
      最近更新 更多