自定义视图控制器上的“编译器错误”,“分段错误11”

时间:2012-07-29 01:48:45

标签: objective-c uiview uiviewcontroller core-animation ios5

我有一个非常奇怪的问题,我想我知道为什么我会得到它但我似乎无法想到修复。我确信这里没有编译器错误。我有很多这些,所有这些都是因为我的错误代码而发生的。

基本上,我有一个名为UnlockKeyboardViewController的视图控制器,它继承自UIViewController,以及一个名为UnlockKeyboard的自定义视图(直接从UIView继承)。 UnlockKeyboard的标题如下所示:

@interface UnlockKeyboard : UIView
{
    NSArray *buttons;
    NSArray *passcodeFields;

    UIImage *buttonBackgroundImage;
    UIImage *buttonBackgroundHighlightedImage;
    UIImage *middleButtonBackgroundImage;
    UIImage *middleButtonBackgroundImageHighlighted;
    UIImage *screenBackgroundImage;

    UIImage *infoViewContainerImage;
    UIImage *keypadViewContainerImage;
    UIImage *passcodeFieldsContainerImage;

    UIImage *infoViewImage;
    UIImage *passcodeViewImage;

    UIView *infoViewContainer;
    UIView *keypadViewContainer;
    UIView *passcodeFieldsContainer;

    UIView *infoView;
    UIView *keypadView;
    UIView *passcodeFieldsView;

    UIView *infoToDisplayView; //The view the programmer passes to show in infoView.
}
@property(nonatomic, retain)UIImage *buttonBackgroundImage;
@property(nonatomic, retain)UIImage *buttonBackgroundHighlightedImage;
@property(nonatomic, retain)UIImage *screenBackgroundImage;
@property(nonatomic, retain)UIImage *keypadViewBackgroundImage;
@property(nonatomic, retain)UIImage *infoViewContainerImage;
@property(nonatomic, retain)UIImage *keypadViewContainerImage;
@property(nonatomic, retain)UIImage *passcodeFieldsContainerImage;
@property(nonatomic, retain)UIImage *infoViewImage;
@property(nonatomic, retain)UIImage *passcodeViewImage;
@property(nonatomic, retain)UIView *infoToDisplayView;

//Properties for container views.
@property(nonatomic, retain)UIView *infoViewContainer;
@property(nonatomic, retain)UIView *keypadViewContainer;
@property(nonatomic, retain)UIView *passcodeFieldsContainer;

@end

到目前为止,UnlockKeyboardViewController实现如下所示:

@implementation UnlockKeyboardViewController
-(id)init
{
    if((self = [super init]))
    {
        self.view = [[UnlockKeyboard alloc] init];
    }
    return self;
}

-(void)viewDidLoad
{
    [super viewDidLoad];
}

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIView animateWithDuration:0.7 animations:^{
        self.view.keypadViewContainer.frame = CGRectMake(0, 261, 320, 200);
    } completion:^(BOOL finished){

    }];
}

-(void)dealloc
{
    [super dealloc];
}
@end

这是我的问题变得有趣。每当我尝试编译时,终端(这是一个越狱应用程序,所以没有Xcode)给我以下错误:

In function ‘void __-[UnlockKeyboardViewController viewDidAppear:]_block_invoke_1(void*)’:
Segmentation fault: 11
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://developer.apple.com/bugreporter> for instructions.

但是,只有在我输入以下内容时才会出现此错误:

self.view.keypadViewContainer.frame = CGRectMake(0, 261, 320, 200);

如果我在动画块中没有那行,编译器就不会给我这个错误,而且编译就好了。虽然,无论我把这条线放在哪里,我总是得到分割线11。

我认为这可能与UIView没有名为keypadViewContainer的成员这一事实有关,尽管UnlockKeyboard具有该属性并且是UIView的子类。我相信这是因为编译器实际上看不到UIView和UnlockKeyboard之间的类层次结构。

如果我是对的,我不知道如何解决这个问题。想了一会儿。任何帮助我解决这个问题的输入都将非常感激。

1 个答案:

答案 0 :(得分:0)

首先,您应该只在其loadView方法中设置视图控制器的视图属性:

- (void)loadView
{
    self.view = [[UnlockKeyboard alloc] init];
}

这将触发其他方法,例如viewDidLoad,它们将期望对象已完全初始化。故事的道德:在控制器要求之前不要设置view属性。

然后,在您的viewDidAppear:方法中,将view属性包含在您正在使用的特定子类中应避免任何警告,并希望奇怪的编译器崩溃:

[UIView animateWithDuration:0.7 animations:^{
    UnlockKeyboard *ukView = (UnlockKeyboard *)self.view;
    ukView.keypadViewContainer.frame = CGRectMake(0, 261, 320, 200);

您编写的代码应该触发编译器警告,因为keypadViewContainer上没有定义属性UIView(表达式self.view的类型)。

类型转换肯定有点难看,但它是必要的,因为视图控制器是一个通用的父类,并且不知道它控制的是什么类型的视图。您可能会发现定义一个不需要一直执行转换的属性很有用:

@property (nonatomic,readonly) UnlockKeyboard *unlockKeyboardView;

和相应的方法:

- (UnlockKeyboard *)unlockKeyboardView
{
    return self.view;
}