问题描述
||
我正在用代码(没有IB)完全制作UIView的子类,我们将其称为ContentView。在此视图中,我已经为声音和视频设置了多个播放器,以及几个imageView(没什么特别的)。
接下来,我计划多次对ContentView进行子类化,以便为每个视图加载不同的媒体。所有这些视图都将具有相同的视图控制器,因为所有接口的界面都相同,只有内容(声音,视频和图像)会发生变化。
因此,我要解决此问题的方法是在ContentView.h中声明几个ѭ0,并以ѭ1的形式在ContentView的每个子类视图的实现文件中指定其键/值,因为我将重用它们为每个加载不同的媒体查看并且不希望它们出现在全局名称空间中。
这是一些样机代码,说明了我在说什么:
在ContentView.h中
@interface ContentView : UIView {
Nsstring *const kSoundFile1;
Nsstring *const kSoundFile2;
Nsstring *const kSoundFileType;
Nsstring *const kMovieFile1;
Nsstring *const kMovieFile2;
Nsstring *const kMovieFileType;
Nsstring *const kImage1;
Nsstring *const kImage2;
在ContentView.m中,
@implementation ContentView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
Nsstring *filePath1 = [[NSBundle mainBundle] pathForResource: kSoundFile1
ofType: kSoundFileType;
NSURL *url1 = [[NSURL alloc] initFileURLWithPath:filePath1];
AVAudioPlayer *audioPlayer1 = [AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[audioPlayer1 preparetoPlay];
[url1 release];
...等等,对于其余的声音文件和电影(图像除外,我使用的是imageNamed:
)。
然后,在ContentView的每个子类的实现文件中,我就这样:
@implementation ContentViewSubclass
static Nsstring *const kSoundFile1 = @\"sound1\";
static Nsstring *const kSoundFile2 = @\"sound2\";
static Nsstring *const kSoundFileType = @\"wav\";
static Nsstring *const kMovieFile1 = @\"movie1\";
static Nsstring *const kMovieFile2 = @\"movie2\";
static Nsstring *const kMovieFileType = @\"mov\";
static Nsstring *const kImage1 = @\"image1.png\";
static Nsstring *const kImage2 = @\"image2.png\";
@end
我无法完成这项工作。没有编译器错误或警告,只是没有任何播放或显示。我是在做错什么,还是这不是解决问题的正确方法?
我真的很感谢一些见解。提前致谢。
解决方法
尽管来自@deanWombourne的以下答案非常合理,但我对他的解决方案有疑问。但是我发现了问题所在(至少这是我的看法,并且现在可以正常工作)。
UIView子类已经有自己指定的初始化器,即
-(id)initWithFrame
,因此在ContentView的任何后续子类上调用-(id)init
都不会更新任何实例变量,因为[super init]
无处指向(或者更好,首先,超类运行first9ѭ,然后才运行init
,等于什么也没做。
所以我的解决方案如下:
(将ContentView.h的ivars更改为NSString *pointer
的形式,例如NSString *kSoundFile1
之后),
@implementation ContentViewSubclass
- (id)initWithFrame:(CGRect)frame {
kSoundFile1 = @\"sound1\";
kSoundFile2 = @\"sound2\";
kSoundFileType = @\"wav\";
kMovieFile1 = @\"movie1\";
kMovieFile2 = @\"movie2\";
kMovieFileType = @\"mov\";
kImage1 = @\"image1.png\";
kImage2 = @\"image2.png\";
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
@end
首先更新指定的初始化程序-(id)initWithFrame
上的字符串,然后才调用super。
现在工作正常。
衷心感谢@deanWombourne为解决此问题所提供的帮助。
, 我想我可能已经解决了,请忽略其他答案:)
您已将字符串设置为ContentView的成员(在ContentView.h中)。他们开始时是15英镑。
然后,在每个子类中,使用相同的名称(但仅在该.m文件中)创建新的字符串(使用static关键字即可!)。只是因为它们在C代码中具有相同的名称并不意味着它们指向相同的对象:)
您的ContentView.m文件看不到新字符串,它仅使用.h文件中定义的字符串,这些字符串从未设置为任何值,因此我敢打赌它们仍然是15美元!
您需要像这样在子类中定义字符串:
@implementation ContentViewSubclass
- (id)init {
self = [super init];
if (self) {
kSoundFile1 = @\"sound1\";
kSoundFile2 = @\"sound2\";
kSoundFileType = @\"wav\";
kMovieFile1 = @\"movie1\";
kMovieFile2 = @\"movie2\";
kMovieFileType = @\"mov\";
kImage1 = @\"image1.png\";
kImage2 = @\"image2.png\";
}
return self;
}
@end
PS这些名字前面的k
不再有意义-我会摆脱它)
, 编辑:这个答案是完全吠叫了错误的树。试试这个吧:)
我立即寻找这条线:
AVAudioPlayer *audioPlayer1 = [AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
SDK希望告诉您错误,但您不希望这样做。然后,您抱怨没有错误!
尝试这个:
NSError *error = nil;
AVAudioPlayer *audioPlayer1 = [AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if (error) {
NSLog(@\"error : %@\",error);
}
让我们知道您所看到的。