我在释放对象后遇到指向垃圾的破碎指针时遇到麻烦。 objectA是另一个对象objectB的回调的委托。
objectA经常被分配和释放(在我的应用程序中,它是菜单UI对象)。每次初始化objectA时,它都会初始化objectB并开始异步操作,然后通过id委托属性回调给objectA。
如何停止指针:id委托中断?

ObjA.m
-(void)dealloc{
     [super dealloc];
}

+(id)init{
     ObjA *objectA = [[ObjA alloc]init];
     return objectA;
}
-(id)init{
     if (self == [super init]){
         ObjB *objectB = [ObjB initialiseWithDelegate:self];

     }
     return self;
}
-(void)callback:(id)arg{
     //This callback is called from an asynchronous routine from  objectB

}
-(void)terminate{
  //This is called when I want to remove/release objectA
  //Other logical termination code here
  [self release];
}


ObjB.m
@synthesize delegate;

+(id)initialiseWithDelegate:(id)delegate{
     ObjB *objectB = [[ObjB alloc]init];
     [objectB setDelegate:delegate];
     return objectB;
}
-(id)init{
     if (self == [super init]){
         [self beginAsynchronousOperation];

     }
     return self;
}
-(void)beginAsynchronousOperation{
     //Do asynchronous stuff here
}
-(void)finishedAsynchronousOperation{
     //Called when asynch operation is complete

     if (self.delegate) [self.delegate callback:someargument]; //EXC error. Pointer broke

}

最佳答案

简短的答案是,当您取消分配objectA时,您将nil移出了objectB的delegate属性。如您所见,由于委托是分配的,而不是保留的(这是为了防止发生保留周期,因此很明显),当“拥有”对象消失时,委托引用可以挂起。通常,objectA将保留对objectB的保留引用,并且在objectA的dealloc期间,它将首先将objectB的delegate设置为nil,然后将release设置为objectB。这样可以防止崩溃。当然,这假设(通常)假设您不需要对该异步完成执行任何操作。它还假设对象A在异步操作过程中可以安全地释放它。这通常适用于(例如)动画,但是如果您要构建自己的任务,则可能需要注意此处的生命周期。

此代码段上的一些注释可能会有所帮助:


创建后,您的objectA实际上并没有持有对objectB的引用。这意味着您不能取消委托。创建对象B时,应保留对其的引用,以便执行此操作。
您正在泄漏objectB。 ObjectA创建了它(alloc,init),但是随后删除了引用,因此即使完成引用,似乎也没有人负责释放它。同样,握住它以便可以释放它也可以解决此问题。
您在objectA上的-terminate是一种反模式-一个对象永远不应(仅一个例外:init内部的故障)在-release上调用self。对象应由其所有者(最初创建该对象的所有者)释放。
您的if (self == [super init])模式通常用一个等号书写,这意味着您既要向结果分配self,又要检查结果是否为nil。这是可可历史上的古怪之处,在这里可能没有什么不同,但值得指出。

关于objective-c - 回调麻烦的objective-c损坏的指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12249857/

10-12 01:19