我在代码中完全使用UIView的子类(没有IB),我们称之为 ContentView 。在这个视图中,我已经为声音和视频设置了几个播放器,以及几个imageViews(没什么特别的)。
接下来,我计划多次继承 ContentView ,以便为每个视图加载不同的媒体。所有这些视图都具有相同的视图控制器,因为所有这些视图的界面都是相同的,只有内容(声音,视频和图像)会发生变化。
所以我解决这个问题的方法是在 ContentView .h中声明几个NSString *const
,并在 ContentView的每个子类视图的实现文件中指定它们的键/值,以static NSString *const
的形式,因为我将重复使用它们为每个视图加载不同的媒体,并且不希望它们出现在全局名称空间中。
这是一些模拟代码,说明了我在说什么:
在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
我无法完成这项工作。没有编译器错误或警告,只是没有播放或显示。我做错了什么,或者这不是解决问题的正确方法?
我真的很感激一些见解。提前谢谢。
答案 0 :(得分:1)
虽然@deanWombourne的答案非常有道理,但我的解决方案存在问题。但是我发现它有什么问题(至少这是我对它的看法,现在它正在运作)。
UIView子类已经有了自己的指定初始值设定项-(id)initWithFrame
,因此在 ContentView 的任何后续子类上调用-(id)init
都不会更新任何实例变量[super init]
指向无处(或者更好,首先超类运行initWithFrame
,然后才运行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在解决这个问题方面提供的帮助。
答案 1 :(得分:0)
我立即寻找这条线:
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);
}
让我们知道你看到了什么。
答案 2 :(得分:0)
我想我可能已经解决了,忽略了我的另一个答案:)
您已将字符串设置为ContentView的成员(在ContentView.h中)。他们开始初始化为nil
。
然后,在每个子类中,您创建具有相同名称但仅在该.m文件中的 new 字符串(static关键字执行此操作!)。只是因为它们在C代码中具有相同的名称并不意味着它们指向同一个对象:)
您的ContentView.m文件无法看到新字符串,它只使用.h文件中定义的字符串,这些文件从未设置为任何内容,所以我敢打赌它们仍然是nil
!
您需要在子类中定义字符串,如下所示:
@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
已经没有多大意义了 - 我已经摆脱它了)