-1

大家好,我是 Objective c 的新手,我正在寻找类似 c++ 或 java 的方法来初始化另一个UIViewController类的对象属性。

所以我使用了 -init 函数,它似乎工作得很好,但问题是,经过一些调试后,我发现即使我的属性(an )在启动时NSString成功初始化,它也会删除(初始化)我在 init 中所做的一切所以我不能用我的!我想播放视频链接,但我发现转到方法的字符串为空。另请注意,当我初始化视频中的流时,会立即播放。-initviewDidLoadpropertyplayTheVideoviewDidLoad

这是我的代码:

按钮控制器.m

#import "ButtonsController.h"
#import "PlayVideoController.h"

@interface ButtonsController ()

@end

@implementation ButtonsController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    **UPDATE:[self createButton];**
}

-(void)createButton {

PlayVideoController *newObject = [[PlayVideoController alloc] initWithString:@"--somestring--" ];
[newObject playTheVideo];

}

播放视频控制器.m

#import "PlayVideoController.h"

@interface PlayVideoController ()

@end

@implementation PlayVideoController

@synthesize stream;
@synthesize player;


- (void)viewDidLoad
{
    [super viewDidLoad];

    [self playTheVideo];
}


- (id) initWithString: (NSString*) theStream {
    self = [super init];
    if (self) {
        stream = theStream;
    }
    return self;
}

- (void) playTheVideo {

    NSURL *url = [NSURL URLWithString:stream];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [player loadRequest:request];
}

播放视频控制器.h

#import <UIKit/UIKit.h>

@interface PlayVideoController : UIViewController

@property NSString *stream;

@property (weak, nonatomic) IBOutlet UIWebView *player;
- (void) playTheVideo;
- (id) initWithString: (NSString*) theStream;

@end

我在主类中创建一个对象只是为了快速启动它

编辑:删除 main.m 中的操作并保留默认值

4

3 回答 3

2

问题是你在你的main函数中创建了这个控制器,但不要对它做任何事情,它会超出范围(如果使用 ARC,将被释放)。无论如何,当在应用程序的标准流程中实例化视图控制器时,它将创建第二个实例,这次没有createButton调用。所以你的呼唤是createButton徒劳main的。“我在主类中创建一个对象只是为了快速启动它”的概念并没有通过集合。视图控制器的创建CreateButtons遇到了类似的问题。

您确实需要在stream其他地方设置属性(例如,在viewDidLoadPlayVideoControllerprepareForSegue的视图控制器中,它是 segueing to PlayVideoController)。但是您几乎可以肯定永远不会要求initWithStringPlayVideoController并且您可能可以停用该方法)。

例如,如果您通过故事板标识符为 的 segue从ButtonsController视图控制器转换到视图控制器,那么您可以像这样使用in :PlayVideoControllerplayVideoprepareForSegueButtonsController

#import "PlayVideoController.h"

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"playVideo"]){
        PlayVideoController *controller = (PlayVideoController *)segue.destinationViewController;
        controller.stream = @"--somestring--";
    }
}

(有关在控制器之间传递数据,请参阅此答案的“使用 segues 传递数据”部分。)

如果您想在启动时做一些事情,例如初始化一些模型对象结构(但不是视图控制器),您可以在您的应用程序委托中执行此操作didFinishLaunchingWithOptions,但到目前为止与我们共享的内容似乎表明这是必要的。但是如果你这样做,请确保你做了必要的内存管理来保持它(例如,让这个模型对象成为应用程序委托的属性,让它成为一个单例,等等)。但是,如果您创建一个局部变量并对其进行配置并让它超出范围,您将失去您在该变量上所做的工作。

于 2013-11-12T20:01:39.860 回答
1

您的属性应指定其内存管理的属性以及它是原子的还是非原子的。

所以而不是 @property NSString *stream;

你应该写

@property (copy, nonatomic) NSString *stream;

您不再需要写作@synthesize,因为这已为您处理好了。

最后,在您的初始化程序中,您需要使用下划线直接访问 iVar。

所以应该说_stream = [theStream copy];

编辑:

将您的吸气剂更改为self.stream

于 2013-11-12T19:28:15.267 回答
0

你应该更新你的 PlayVideoController.h 文件如下

#import <UIKit/UIKit.h>

@interface PlayVideoController : UIViewController

@property (strong, nonatomic) NSString *stream;
@property (weak, nonatomic) IBOutlet UIWebView *player;

- (void) playTheVideo;
- (id) initWithString: (NSString*) theStream;

@end

它应该工作。

于 2013-11-12T19:39:49.050 回答