ARC Objective-C:如何自我解除分配?

时间:2013-01-20 17:31:53

标签: objective-c cocoa automatic-ref-counting memory-management

我正在创建一个浏览网站的工作流程,工作流程的每一步都必须加载n帧,然后知道它已准备就绪(我必须实现超时)。

我不明白为什么[self next]给我这个错误: * - [WebWorkflow next]:发送到解除分配的实例的消息0x105796ef0

考虑这个委托功能:

- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
    frameCounter++;
    NSInteger frames = [(WebWorkflowStep *)[steps objectAtIndex:index] frames];
    NSLog(@"Frame counter %ld of %ld", frameCounter, frames);
    [self next];
}

下一个方法:

-(void) next
{
    if ( index < [steps count])
    {
        frameCounter = 0;
        index = index + 1;
        WebWorkflowStep *step = [steps objectAtIndex:index-1];
        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:step forKey:@"selector"];
        [[NSNotificationCenter defaultCenter] postNotificationName:EVENT_WORKFLOW_NEXT object:nil userInfo:userInfo];

    }
}

注意:

- WebWorflow a.k.a'self'已由另一个强大的

类创建/绑定

像这样:

@interface AController : NSObject <APIProtocol>
{
    WebView *webview;
    NSMutableArray *accounts;

    WebWorkflow *workflow;
}

@property (strong) WebWorkflow *workflow;

...

我确实创建了这样的工作流程:

workflow = [[WebWorkflow alloc] initWithWebView:webview];
    NSArray *getPicturesWorkflow = [NSArray arrayWithObjects:
                                            [[WebWorkflowStep alloc] initWithSelector:@"open" andLoadFrames:0],
                                            [[WebWorkflowStep alloc] initWithSelector:@"login" andLoadFrames:2],
                                            [[WebWorkflowStep alloc] initWithSelector:@"getPictures" andLoadFrames:8],
                                             nil];
            [workflow setSteps:getPicturesWorkflow];

它被初始化为:

-(id)initWithWebView:(WebView *)webview
{
    self = [ super init];
    if(self) {
        timeout = 10;
        index = 0;
        web = webview;
        frameCounter = 0;
        [web setFrameLoadDelegate:self];
    }
    return self;
}

1 个答案:

答案 0 :(得分:4)

AController实例拥有Web视图,是Web视图的委托。 AController实例正在发布(出于某种原因......我们需要了解它的所有者如何管理它)。因为它可能在加载期间被释放,所以它应该自行清理,如下所示:

- (void)dealloc {
    [web stopLoading:self];  // or webView, not sure what you call it
}

这可以防止崩溃。它也将放弃负载。如果您不想这样做,您需要弄清楚AController实例的发布原因。

这样做的第一步是dealloc方法中的断点。