我正在尝试制作一个播放YouTube视频的课程,但我遇到了一些问题。
以下是我处理YouTube视频的课程:
// this is the only property declared in the .h file:
@property (strong, nonatomic) UIView * view
// the rest of this is the .m file:
#import "MyYouTube.h"
@interface MyYouTube()
@property (strong, nonatomic) NSDictionary * contentData;
@property (strong, nonatomic) UIWebView * webView;
@property (nonatomic) int videoOffset;
@end
@implementation MyYouTube
@synthesize view,contentData,webView,videoOffset;
- (MyYouTube*) initIntoView: (UIView*) passedView withContent: (NSDictionary*) contentDict {
NSLog(@"YOUTUBE: begin init");
self=[super init];
videoOffset=0;
view=[[UIView alloc] initWithFrame:passedView.bounds];
[view setBackgroundColor:[UIColor blackColor]];
[view setAutoresizesSubviews:YES];
[view setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
contentData=contentDict;
NSString * compiledUrl=[[NSString alloc] initWithFormat:@"http://_xxx_.com/app/youtube.php?yt=%@",[contentData objectForKey:@"cnloc"]];
NSURL * url=[[NSURL alloc] initWithString:compiledUrl];
NSURLRequest * request=[[NSURLRequest alloc] initWithURL:url];
webView=[[UIWebView alloc] initWithFrame:passedView.bounds];
[webView loadRequest:request];
[webView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[[webView scrollView] setScrollEnabled:NO];
[[webView scrollView] setBounces:NO];
[webView setMediaPlaybackRequiresUserAction:NO];
[webView setDelegate:self];
NSLog(@"YOUTUBE: self: %@",self);
NSLog(@"YOUTUBE: delegate: %@",webView.delegate);
[view addSubview:webView];
NSLog(@"YOUTUBE: end init");
return self;
}
-(void)webViewDidFinishLoad:(UIWebView*)myWebView {
NSLog(@"YOUTUBE: send play command");
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"playVideo(%d)", videoOffset]];
}
- (void) dealloc {
NSLog(@"YOUTUBE: dealloc");
}
@end
以下是调用此类的代码(此代码位于appDelegate中):
NSLog(@"about to load youtube");
ytObj=[[MyYouTube alloc] initIntoView:mainView withContent:cn];
NSLog(@"loaded youtube");
[mainView addSubview:[ytObj view]];
FYI mainView和ytObj声明为:
@property (nonatomic,strong) UIView * mainView;
@property (nonatomic,strong) MyYouTube * ytObj;
运行此代码时,应用程序崩溃,我在控制台中收到此信息:
about to load youtube
YOUTUBE: begin init
YOUTUBE: self: <MyYouTube: 0x16503d40>
YOUTUBE: delegate: <MyYouTube: 0x16503d40>
YOUTUBE: end init
YOUTUBE: dealloc
loaded youtube
*** -[MyYouTube respondsToSelector:]: message sent to deallocated instance 0x166f19f0
如果我将UIWebView委托设置为nil
,那么该应用不会崩溃,但正如预期的那样,YouTube视频无法自动播放。
任何人都可以向我解释:
为什么对象在发生之后立即解除分配 初始化
为什么将respondsToSelector:
消息发送给
除了MyYouTube之外的其他实例?
如何在不崩溃的情况下让YouTube视频自动播放?
非常感谢。
修改
完全是我的坏 - ytObj是一个强大的财产 - 我忘了提到这一点。我添加了代码以反映这一点。
编辑2
我在dealloc方法上添加了一个断点,这是调用堆栈:
0 -[MyYouTube dealloc]
1 objc-object::sidetable_release(bool)
2 -[MyAppDelegate playYouTube:]
此处的最后一个条目(playYouTube:
)是包含我的应用委托中代码的方法,该代码位于上面的原始帖子中。那么,还有一个问题:
objc-object::sidetable_release(bool)
,它做了什么,为什么要发布我的YouTube对象?答案 0 :(得分:2)
为什么对象在初始化后会立即解除分配?
因为没有东西拥有它。
您将其设置为视图的委托,但UIWebView
的委托属性是assign
属性。该视图不接受其委托的所有权。这意味着当ytObj
超出范围时(可能之前,取决于优化)没有任何拥有它,所以它消失了。
修改强>
您还需要确保在取消分配ytObj时,将其仍为委托的任何视图的委托属性设置为nil。否则视图将继续尝试将消息发送到解除分配的对象。
如果没有应用程序崩溃,如何让YouTube视频自动播放?
您需要确保ytObj
只要作为委托的视图持续,并且在取消分配时,它的视图的委托设置为nil。
另一个小问题。您的-init
函数应在调用self = [super init]
后测试self不为nil。如果self为nil,它不应运行任何其余的初始化代码。
答案 1 :(得分:1)
1)(我的第一个问题的第一个答案,在你编辑之前)
这种情况正在发生,因为您正在使用ARC(自动引用计数)并且您没有保留本地&#34; ytObj
&#34;在您创建它的对象中的变量((不是&#34; self.ytObj
&#34;属性)。一旦创建了本地&#34; ytObj
的函数&#34;变量完成并返回,对象自动解除分类。
改变这个:
ytObj=[[MyYouTube alloc] initIntoView:mainView withContent:cn];
到此:
self.ytObj=[[MyYouTube alloc] initIntoView:mainView withContent:cn];
对于&#34;最佳做法&#34;,我还建议您不要在应用程序委托中执行太多工作和/或代码。应用程序代表意味着接收特定于应用程序的消息(例如&#34;应用程序正在暂停&#34;,&#34;应用程序再次变为活动状态&#34;等等),您应该在子类视图中执行此类操作控制器。
2)
&#34; respondsToSelector:
&#34;您看到的错误是因为您的YouTube对象已自动解除分类错误。如果它仍然存在,你就不会看到这个消息。
3)
如果您在此处搜索Stackoverflow,您将找到解释如何进行自动播放的其他问题和解答... like how about this one?
答案 2 :(得分:0)
对象ytObj
因为在任何地方都没有强引用,它只存在于定义的范围内。代表大部分时间都被宣布为弱房产。没有人坚持引用这个对象,因此ARC发布它
为ytObj
创建一个强大的属性,您将看到一切正常。