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

时间:2013-11-12 19:21:48

标签: ios objective-c uiviewcontroller init viewdidload

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

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

这是我的代码:

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

#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

#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中的操作并保留默认值

3 个答案:

答案 0 :(得分:2)

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

您确实需要在其他位置设置stream属性(例如viewDidLoad的{​​{1}}或PlayVideoController视图控制器中的prepareForSeguePlayVideoController 1}})。但是你几乎肯定永远不会为initWithString调用PlayVideoController(你可能可以退出该方法)。

例如,如果您通过带有情节提要标识符(例如ButtonsController)的segue从PlayVideoController视图控制器转换到playVideo视图控制器,那么您可以使用{{ 1}} prepareForSegue就像这样:

ButtonsController

(请参阅this answer about passing data between controllers的“使用segues向前传递数据”部分。)

如果您想在启动时做某事,例如初始化一些模型对象结构(但不是视图控制器),你可以在你的app委托#import "PlayVideoController.h" - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if([segue.identifier isEqualToString:@"playVideo"]){ PlayVideoController *controller = (PlayVideoController *)segue.destinationViewController; controller.stream = @"--somestring--"; } } 中做到这一点,但到目前为止我们没有任何共享,似乎表明这是必要的。但是如果你这样做,请确保你做了必要的内存管理来保持它(例如,使这个模型对象成为app委托的属性,使其成为单身,等等)。但是如果你创建一个局部变量并对其进行配置并让它超出范围,你就会失去你在那里所做的工作。

答案 1 :(得分:1)

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

所以而不是 @property NSString *stream;

你应该写

@property (copy, nonatomic) NSString *stream;

您不再需要编写@synthesize,因为这会照顾您。

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

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

编辑:

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

答案 2 :(得分: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

它应该有用。