0

我让 AdView 像这样扩展 UIView

广告视图:

//nerver call dealloc when adview release
-(void)dealloc
{
   //stop thread
   bStart = NO;
   //...
   [super dealloc];
}
-(id)init
{ 
    //.....
    bStart = YES;
    //the self will retain by NSThread,i try to call [self performBackground..:onThrad] or timer the same too.
    NSThread* thead = [[NSThread alloc] initWithTagert:self ...:@select(onThread)];
    [thread start];
    [thread release];
}
-(void)onThread
{
   while(bStart)
   {
       //....
    }
}

控制器

{
    AdView* view = [[AdView alloc] init];
    view.delegate = self;// i am ture delegate is not retain
    [self.view addSubView:view];

    [view release]
}

Adview从来没有在contoller发布时调用dealloc,谁知道如何修复它。

4

2 回答 2

2

正如其他人指出的那样,您正在传递self给保留它的目标初始化。这就是为什么你有一个额外的保留导致对象没有被释放。

也就是说,让我在这里给你两条建议:

  1. 使用弧。现在是 2013 年,我们遭受手动引用计数的困扰已经有足够长的时间了。
  2. 使用 GCD。现在是 2013 年,我们遭受手动线程管理的困扰已经有足够长的时间了。

您的代码的现代版本看起来像

- (instancetype)init { 
    //...
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self doStuffAsynchronously];
    });
    //...
}

- (void)doStuffAsynchronously { ... }

编辑

正如评论中 JFS 建议的那样,如果您需要启动和停止后台执行,您应该考虑NSOperationNSOperationQueue. 一个幼稚(但仍然有效)的实现将是:

@property (nonatomic, strong) NSOperationQueue * operationQueue;

//...

- (instancetype)init {
    //...
    self.operationQueue = [NSOperationQueue new];
    [operationQueue addOperationWithBlock:^{
        [self doStuffAsynchronously];
    }];
    //...
}

- (void)doStuffAsynchronously { ... }

- (void)stopDoingStuff {
    [self.operationQueue cancelAllOperations];    
}

不过,一种更简洁的方法是子类化NSOperation,通过将其添加到队列来启动它并通过调用来停止它stop

于 2013-08-28T09:22:26.890 回答
0

线程将目标保留 selfstart. 所以只要线程运行,对象就不会消失。

控制器应该通过调用类似的东西来停止线程adView.bStart = NO;(当然你必须实现)。

于 2013-08-28T09:14:05.750 回答