Ios 对象在初始化后立即解除分配
我试图制作一个播放YouTube视频的课程,但我遇到了几个问题 这是我处理YouTube视频的班级:Ios 对象在初始化后立即解除分配,ios,objective-c,uiwebview,youtube,Ios,Objective C,Uiwebview,Youtube,我试图制作一个播放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,
// 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中):
仅供参考,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
这里的最后一个条目(playYouTube:
)是包含上面原始帖子中的my app delegate中的代码的方法。那么,还有一个问题:
- 什么是
,它做什么,为什么要发布我的YouTube对象objc object::sidetable_release(bool)
ytObj
”变量((它不是“self.ytObj
”属性)。一旦创建本地“ytObj
”的函数变量结束并返回,对象自动解除锁定
更改此项:
ytObj=[[MyYouTube alloc] initIntoView:mainView withContent:cn];
为此:
self.ytObj=[[MyYouTube alloc] initIntoView:mainView withContent:cn];
对于“最佳实践”,我还建议不要在应用程序委托中执行太多工作和/或代码。应用程序委托旨在接收特定于应用程序的消息(如“应用程序正在暂停”、“应用程序正在重新激活”等),您应该在子类视图控制器中执行类似操作
(二)
您看到的“响应选择器:
”错误是因为您的YouTube对象已自动解除锁定。如果它还活着,你就看不到这个信息了
(三)
如果您在这里搜索Stackoverflow,您将找到其他解释如何进行自动播放的问题和答案 对象
ytObj
因为在任何地方都没有强引用,所以它只存在于定义的范围内。委托在大多数情况下被声明为弱属性。没有人保留对此对象的强引用,因此ARC将释放它。为
ytObj
创建一个强大的属性,您将看到一切正常
为什么对象在初始化后立即解除分配
因为没有人拥有它
您将其设置为视图的委托,但UIWebView
的委托属性是assign
属性。视图不拥有其委托的所有权。这意味着当ytObj
超出范围时(可能在之前,取决于优化),没有任何东西拥有它,所以它就消失了
编辑
您还需要确保在解除分配ytObj时,将它仍然是其委托的任何视图的委托属性设置为nil。否则,视图将继续尝试向解除分配的对象发送消息
我怎样才能让YouTube视频自动播放而不让应用程序崩溃
您需要确保ytObj
的持续时间与它作为委托的视图的持续时间一样长,并且当它被解除分配时,它的视图的委托被设置为nil
另一个小问题。调用
self=[super init]
后,您的-init
函数应该测试self是否为nil。如果self为nil,则不应运行任何其他初始化代码。完全正确!事实上,您只对ytObj.view
有很强的引用,而不是对象本身!完全是我的错-ytObj是一个强大的财产-我忘了提到这一点。我添加了代码来反映这一点。完全是我的坏-ytObj是一个强大的属性-我忘了提到这一点。我添加了代码来反映这一点。当对象被解除分配时,将委托设置为nil似乎是可行的。我不明白为什么youtube对象在被释放后工作正常,这对我来说毫无意义。但是非常感谢你的帮助——我将进一步测试一下,如果它继续有效,我将标记你是正确的。再次感谢,这个问题已经让我发疯快两个星期了@吉米,我想这是因为它不是同一个例子。不知何故,我认为创建ytObj的代码以及与之配套的视图被执行了不止一次。第二次执行时,对第一个ytObj的强引用消失了,但视图仍然存在,并试图向其(现在不存在)委托发送消息。完全是我的错-ytObj是一个强属性-我忘了提到这一点。我添加了代码来反映这一点。在alloc&init'ing时使用“self.ytObj
”@jimmeryi刚刚这样做了,这没有什么区别:(因为with ARC实例变量(ytObj是)自动strong
,除非另有声明。此答案中的两个赋值都会创建强引用。问题在于,当ytObj被释放时,视图的委托未设置为nil(tut解释了为什么日志消息中的指针值不同).出于好奇,你能在dealloc
中放置一个断点,看看它从哪里被调用(查看调用堆栈)?@alex-i我刚刚为你添加了调用堆栈。
ytObj=[[MyYouTube alloc] initIntoView:mainView withContent:cn];
self.ytObj=[[MyYouTube alloc] initIntoView:mainView withContent:cn];