Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/108.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 对象在初始化后立即解除分配_Ios_Objective C_Uiwebview_Youtube - Fatal编程技术网

Ios 对象在初始化后立即解除分配

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,

我试图制作一个播放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中):

仅供参考,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中的代码的方法。那么,还有一个问题:

  • 什么是
    objc object::sidetable_release(bool)
    ,它做什么,为什么要发布我的YouTube对象
1)(在编辑之前,我对您的第一个问题的第一个回答)

之所以会发生这种情况,是因为您正在使用ARC(自动引用计数),并且没有在创建它的对象中保留本地“
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];