我有一个继承MPMoviePlayerViewController
的类。我尝试重写init
方法,以便我不必为每个其他-initWithSomething
函数重复代码。对于自定义initWithSomething方法,这将起作用。但我无法弄清楚如何使其适用于继承的iniWithSomething方法
-(instancetype)init
{
if(self = [super init]){
// This is code I don't want to repeat in initWithSomething methods
[self startWithHiddenControls];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(UIApplicationDidBecomeActive)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
return self;
}
-(instancetype)initWithContentURL:(NSURL *)contentURL
{
// Not overwriting doesn't use my overwriten init so i must do it.
// But how ?!?
// why [super init] makes inifinite loop? (I know the norm is [super <same method>])
if(self = [self init]){} // this will not work. Inifinite loop I believe.
return self;
}
//This method works fine
- (instancetype)initWithSettings:(NSDictionary *)settings
{
// [self init] works here but HOW?
if(self = [self init]){
//my custom stuff
}
}
在写这篇文章的过程中,我发现[super init]
调用-(instancetype)initWithContentURL:(NSURL *)contentURL
并存在无限循环问题。为什么指定的初始值设定项init
会调用辅助初始值设定项initWithURL
?它应该不是相反吗?请解释一下。
这是否意味着我应该使用initWithURL
方法而不是init
方法来放置我不想重复的代码。
编辑:这就是我所做的。我在initWithURL方法中输入了代码。现在,默认的init和我的自定义init都将运行它。
答案 0 :(得分:2)
为什么要将init
称为指定的初始值设定项?我相信,事实并非如此。我们来参考the docs:
指定的初始值设定项在类中起着重要作用。它 确保通过调用初始化继承的实例变量 超类的指定初始值设定项。 通常是 init ...具有最多参数且大部分参数的方法 初始化工作,它是辅助的初始化程序 该类的初始化程序调用自己的消息。
所以它似乎并不满足这两个特征:它具有最少数量的参数,显然它用initWithContentURL
调用另一个初始值设定项(self
)。所以,我相信,如果你找到真正的指定初始化程序,一切都会按预期工作。
根据MPMoviePlayerViewController class reference,指定的初始值设定项为initWithContentURL
。因此,您只需覆盖它而不是init
。
答案 1 :(得分:0)
只需创建一个私有方法并将您的公共代码放在那里,例如
- (void)commonInitialization {
[self startWithHiddenControls];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(UIApplicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
}
然后在你的inits中使用:
- (instancetype)initWithContentURL:(NSURL *)contentURL {
self = [super initWithContentURL:contentURL];
if (self) {
[self commonInitialization];
// everything else
}
return self;
}