在[super init]之前执行某些操作objective-c

问题描述:

我想在调用[super init]之前在派生对象中设置成员变量。 我能找到的就是你不应该做这样的事情。无论如何,我的工作无疑是有效的,但实际上我很想知道在遵守规则时会产生什么后果。如果有正确的方法来处理这个问题,甚至会更好。在[super init]之前执行某些操作objective-c

的详细信息:

我有绑定一个C几个包装++对象到一个Objective-C objec(主要是UI ...查看或UI ...控制器)

@interface my_scrollview : UIScrollView 
{ 
    my_c_class* m_p; 
} 
-(id) initWithFrame:(CGRect)frame wrapper: (my_scrollview*) pWrap; 
-(void) setContentOffset:(CGPoint)contentOffset; 
@end 
@implementation dwin_scrollview_ios 
-(id) initWithFrame:(CGRect)frame wrapper: (my_scrollview*) pWrap 
{ 
    m_p = pWrap; // illegal but works? 
    return [super initWithFrame: frame]; 
    //m_p = pWrap; // to late because [super init...] already called overriden func. 
} 

在我重写setContentOffset-method我需要访问我的C++ - Object。 问题出现是因为initWithFrame使用setContentOffset内部初始化其内容。所以这个方法在我可以“legaly”建立到我的C++对象的链接之前被调用。

如果设置了m_p,我可以通过检查来实现我的覆盖(幸运的是它被初始化为零)。但是我必须在init方法之后同步视图的状态和我的C++对象。在这个例子中,这没有什么大不了,但其他这样的实现要复杂得多,而且我最终得到了很多重复初始化步骤的代码,或者以其他方式使我重新同步,尽管在[super init ...]之前我知道我同步。

有没有一种模式来解决这个正确的(和优雅的)?

在调用[super init ..];之前int指针真的很糟糕吗?

(我假设一个后果是,这种崩溃,如果[超级初始化]返回nil ...?任何其他情况下?)提前

感谢 莫里茨

+0

也许我错过了什么,但为什么这是非法的? Swift鼓励这种初始化。 –

+0

例如。苹果文档:https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/Initialization/Initialization。html#// apple_ref/doc/uid/TP40010810-CH6-SW58我发现了其他的文档可以说是相同的,但是没有人会告诉我们这是一个经验法则还是为什么你不能这么做...... – moritz

+0

https:// developer。 apple.com/library/ios/documentation/General/Conceptual/CocoaEncyclopedia/Initialization/Initialization.html#//apple_ref/doc/uid/TP40010810-CH6-SW58 – moritz

有什么魔力在Objective-初始化方法C。 alloc返回所需类的对象,并将所有实例变量初始化为0/nil/NULL/0.0等。然后,每个init方法只执行开发人员编写的代码。

有些东西显然是愚蠢的,比如设置超类的实例变量,然后调用[super init],并立即覆盖它。你需要知道,init不一定会返回self,而是一个不同的对象,在这种情况下,在调用[super init]之前,你在基类中初始化的所有东西都将消失。

您正在使用错误的init

试试这个:

-(id) initWithFrame:(CGRect)frame wrapper: (my_scrollview*) pWrap 
{ 
    self = [super initWithFrame: frame]; 
    if (self) { 
     m_p = pWrap; 
    } 
    return self; 
} 
+0

'my_scrollview * scroll = [[my_scrollview alloc] initWithframe:.. ..]。 [scroll setContentOffset:....] ' – AleyRobotics

+1

问题是,当initWithFrame调用其他成员方法(例如setContentOffset) – moritz

// illegal but works? 

不,这不违法。尽管非常规,在它的超类初始化程序运行之前,它对一个对象做东西是完全合法的。它可能仍然会导致意想不到的行为和错误,但它本身并不是非法的。有时甚至有必要,例如当你想执行一些计算并将计算结果委托给超类的初始化器时。

+0

时,我希望m_p已经有效。那么为什么downvote? –