使用通过 ViewController 从 XIB 加载的子视图中的对象时出错

Posted

技术标签:

【中文标题】使用通过 ViewController 从 XIB 加载的子视图中的对象时出错【英文标题】:Error by using objects in Subview loaded from XIB with ViewController 【发布时间】:2013-06-23 12:25:03 【问题描述】:

我刚刚创建了一个带有音频播放器接口的 Xib(播放按钮、停止按钮、音量滑块、时间滑块)。我将文件所有者连接到 AudioPlayerViewController,并通过连接到 ViewController 从 Objects 和 IB Action 创建了一些 Outlets。

现在我将此 ViewControllers 视图添加为 UIScrollview 中的子视图。如果我现在使用这些对象之一,我会收到不同的错误:

首先是时间滑块。存在值已更改的 IBAction:

 2013-06-23 14:14:55.448 Bookshelf[17323:907] -[__NSMallocBlock__ CurrentPlayTimeChanged:]: unrecognized selector sent to instance 0x1dd69500
2013-06-23 14:14:55.450 Bookshelf[17323:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSMallocBlock__ CurrentPlayTimeChanged:]: unrecognized selector sent to instance 0x1dd69500'
*** First throw call stack:
(0x31e1d2a3 0x39cd897f 0x31e20e07 0x31e1f531 0x31d76f68 0x33d100c5 0x33d10077 0x33d10055 0x33d0f90b 0x33df0d07 0x33d0f507 0x33c2e421 0x31df26cd 0x31df09c1 0x31df0d17 0x31d63ebd 0x31d63d49 0x3592f2eb 0x33c79301 0x680dd 0x3a10fb20)
libc++abi.dylib: terminate called throwing an exception

第二个按钮:

2013-06-23 14:16:36.842 Bookshelf[17339:907] -[__NSArrayM Audiostopped:]: unrecognized selector sent to instance 0x1fdb1480
2013-06-23 14:16:36.844 Bookshelf[17339:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM AudioStopped:]: unrecognized selector sent to instance 0x1fdb1480'
*** First throw call stack:
(0x31e1d2a3 0x39cd897f 0x31e20e07 0x31e1f531 0x31d76f68 0x33d100c5 0x33d1014d 0x33d100c5 0x33d10077 0x33d10055 0x33d0f90b 0x33d0fe01 0x33c385f1 0x33c25801 0x33c2511b 0x359305a3 0x359301d3 0x31df2173 0x31df2117 0x31df0f99 0x31d63ebd 0x31d63d49 0x3592f2eb 0x33c79301 0xa0dd 0x3a10fb20)
libc++abi.dylib: terminate called throwing an exception

第三音量滑块:

ViewController .h:

#import <UIKit/UIKit.h>

@interface AudioPlayerViewController : UIViewController 
    NSURL * fileURL;


@property (weak, nonatomic) IBOutlet UISlider *volumeSlider;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *AudioStopButton;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *AudioPlay_PauseButton;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *AudioTimeLabel;
@property (weak, nonatomic) IBOutlet UISlider *TimeLineSlider;

@property (nonatomic, strong) NSURL * fileURL;


- (IBAction)volumeChanged:(id)sender;
- (IBAction)AudioStopped:(id)sender;
- (IBAction)AudioPlayPaused:(id)sender;
- (IBAction)TimeLabelPressed:(id)sender;
- (IBAction)CurrentPlayTimeChanged:(id)sender;


@end

ViewController .m:

#import "AudioPlayerViewController.h"

@interface AudioPlayerViewController ()

@end

@implementation AudioPlayerViewController
@synthesize volumeSlider, AudioPlay_PauseButton, TimeLineSlider, AudioTimeLabel, AudioStopButton;
@synthesize fileURL;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) 
        // Custom initialization
    
    return self;


- (void)viewDidLoad


    [super viewDidLoad];
    // Do any additional setup after loading the view.


- (void)didReceiveMemoryWarning

    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.


- (IBAction)volumeChanged:(id)sender 
    NSLog(@"NEW VOL");



- (IBAction)AudioStopped:(id)sender 
    NSLog(@"STOP");



- (IBAction)AudioPlayPaused:(id)sender 
    NSLog(@"PLAY");


- (IBAction)TimeLabelPressed:(id)sender 
    NSLog(@"TIMELABEL");



- (IBAction)CurrentPlayTimeChanged:(id)sender 
    NSLog(@"NEW TIME POS");


@end

添加Subview的.m方法:

- (void) addAudio_index:(int)index 
    AudioPlayerViewController *audiov = [[AudioPlayerViewController alloc] init];
    CGRect frame_s = [[[ScrollView subviews] objectAtIndex:[[ScrollView subviews] count]-1] frame];
    CGRect frame = audiov.view.frame;
    frame.origin.y = frame_s.size.height+frame_s.origin.y;
    frame.origin.x = 0;
    //[audiov.view setFrame:frame];
    UIView *n =[[UIView alloc]initWithFrame:frame];
    [ScrollView addSubview:n];
    [n addSubview:audiov.view];
    [audiov.view setHidden:FALSE];



播放器 XIB: 我想了几个小时,但我不知道任何解决方案,所以也许你可以帮助我......

【问题讨论】:

【参考方案1】:

您的代码保留了AudioPlayerViewControllers 视图(以及所有子视图),但没有保留audiov 实例。因此,当任何视图触发它们的操作时,它们都会调用已被释放的实例。

要解析,创建一个属性并存储audiov(以便保留)。

【讨论】:

如何存储音频?把它放到实例所在的ViewController中的一个数组中就可以了? 不需要是数组,只需一个属性即可:@property (strong, nonatomic) AudioPlayerViewController *audiov; 但问题是,可能插入了 2 或 3 个音频 好的,在这种情况下,是的,使用数组(当它们被移除时,将它们从数组中移除)。

以上是关于使用通过 ViewController 从 XIB 加载的子视图中的对象时出错的主要内容,如果未能解决你的问题,请参考以下文章

Swift:iOS - 通过第三类将数据从 ViewController 传递到 xib 文件

Swift:iOS - 通过3rd类将数据从ViewController传递到xib文件

仅使用一个 ViewController 从 XIB 切换

iOS - 使用 xib 中的 tabBarController 将数据从一个 viewController 传递到另一个 viewController

如何使用 segue 从 Xib 文件加载 viewController?斯威夫特 5

从 xib 调用 viewController