大家好我是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中的操作并保留默认值
答案 0 :(得分:2)
问题是你在main
函数中创建了这个控制器,但是没有对它做任何事情,它将超出范围(如果使用ARC,将被取消分配)。无论如何,当在应用程序的标准流程中实例化视图控制器时,它将创建第二个实例,这次没有调用createButton
。因此,您在createButton
中调用main
是徒劳的。这个“我在主类中创建一个对象以便快速启动它”的概念并没有通过。在CreateButtons
中创建视图控制器会遇到类似的问题。
您确实需要在其他位置设置stream
属性(例如viewDidLoad
的{{1}}或PlayVideoController
视图控制器中的prepareForSegue
。PlayVideoController
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
它应该有用。