简体   繁体   English

初始化Objective c中另一个类的属性

[英]Initialize property from another class in Objective c

Hi guys I'm new to objective c and i was searching for an c++ or java like way to initialize an objects properties from another UIViewController class. 嗨,大家好,我是目标c的新手,我正在寻找一种类似于c ++或java的方法来初始化另一个UIViewController类的对象属性。

So I used the -init function which seems to work terrific, but the problem is that after some debugging I did I found that even though my property (an NSString ) is successfully initialize in -init when the viewDidLoad starts it deletes (initialize) everything I did in init so I can't use my property ! 所以我使用了-init函数,该函数似乎很棒,但是问题是,在进行一些调试后,我发现即使我的属性( NSString )在viewDidLoad启动时在-init成功初始化,它也会删除(初始化)所有内容我做了初始化,所以我不能使用我的property I want to play a video link but I found that the string that goes to playTheVideo method is null. 我想播放视频链接,但发现去playTheVideo方法的字符串为空。 Also note that when I initialize the stream inside viewDidLoad my video plays right away. 还要注意,当我在viewDidLoad初始化流时,我的视频会立即播放。

Here is my code: 这是我的代码:

ButtonsController.m ButtonsController.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];

}

PlayVideoController.m PlayVideoController.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];
}

PlayVideoController.h PlayVideoController.h

#import <UIKit/UIKit.h>

@interface PlayVideoController : UIViewController

@property NSString *stream;

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

@end

I create an object in main class just to start it quickly 我在主类中创建一个对象只是为了快速启动它

EDIT: deleted actions in main.m and left the defaults 编辑:删除main.m中的动作并保留默认值

The issue is that you're creating this controller in your main function, but don't do anything with it and it will fall out of scope (and if using ARC, will be deallocated). 问题在于您正在main功能中创建此控制器,但不对其执行任何操作,并且它将超出范围(并且如果使用ARC,将被释放)。 Regardless, when the view controller is instantiated during the standard flow of the app, it will create a second instance, this time without having createButton called. 无论如何,当在应用程序的标准流程中实例化视图控制器时,它将创建第二个实例,这一次无需调用createButton So your calling of createButton in main is for naught. 因此,您的通话createButtonmain是多余的。 This concept of "I create an object in main class just to start it quickly" doesn't pass muster. “我在主类中创建一个对象只是为了快速启动它”的概念并没有通过。 The creating of the view controller in CreateButtons suffers from an analogous problem. CreateButtons创建视图控制器存在类似问题。

You really need to set the stream property somewhere else (eg in the viewDidLoad of PlayVideoController or in the prepareForSegue of the view controller that is segueing to PlayVideoController ). 您确实需要在其他位置设置stream属性(例如,在PlayVideoControllerviewDidLoad中或在紧接PlayVideoController的视图控制器的prepareForSegue中)。 But you almost certainly will never call initWithString for PlayVideoController (and you probably can retire that method). 但是几乎可以肯定,您永远不会为PlayVideoController调用initWithString (并且您可能可以停用该方法)。

If, for example, you're transitioning from ButtonsController view controller to PlayVideoController view controller via a segue with a storyboard identifier of, say playVideo , then you could use prepareForSegue in ButtonsController like so: 例如,如果您正在通过故事板标识符为playVideo的segue从ButtonsController视图控制器过渡到PlayVideoController视图控制器,则可以在ButtonsController使用prepareForSegueButtonsController所示:

#import "PlayVideoController.h"

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

(See the "Passing data forward using segues" section of this answer about passing data between controllers .) (有关控制器之间的数据传递,请参见此答案的 “使用segues传递数据”一节。)

If you want to do something at startup, eg initialize some model object structure (but not view controllers), you can do that in your app delegate's didFinishLaunchingWithOptions , but there's nothing shared with us thus far that seems to suggest that this is necessary. 如果您想在启动时做一些事情,例如初始化一些模型对象结构(而不​​是视图控制器),则可以在您的应用程序委托的didFinishLaunchingWithOptions ,但是到目前为止,我们之间没有任何共享,这似乎表明这是必要的。 But if you do this, make sure you do the necessary memory management to keep it around (eg make this model object a property of the app delegate, make it a singleton, etc.). 但是,如果执行此操作,请确保进行必要的内存管理以保持不变(例如,使此模型对象成为应用程序委托的属性,使其成为单例,等等)。 But if you create a local variable and configure it and let it fall out of scope, you'll lose the work you did on that. 但是,如果创建一个局部变量并对其进行配置并使其超出范围,那么您将失去在该变量上所做的工作。

Your property should specify attributes for its memory management and whether it is atomic or nonatomic. 您的媒体资源应指定其内存管理的属性,以及它是原子的还是非原子的。

So instead of @property NSString *stream; 所以不是@property NSString *stream;

You should write 你应该写

@property (copy, nonatomic) NSString *stream;

You no longer need to write @synthesize as that is taken care of for you. 您不再需要编写@synthesize因为这已为您解决。

Lastly, in your initializer you need to access the iVar directly by using the underscore. 最后,在初始化程序中,您需要使用下划线直接访问iVar。

So it should say _stream = [theStream copy]; 因此应该说_stream = [theStream copy];

EDIT: 编辑:

Change your getter to self.stream 将您的吸气剂更改为self.stream

You should update your PlayVideoController.h file as below 您应该如下更新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

It should work. 它应该工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM