Ios 如何在另一个对象中保留运行异步任务的对象并成功运行异步任务? 我分别有两个类A和类B的对象 ClassB包含一个很大的方法,我想在后台异步运行它,或者说其他异步线程 我正确地保留了ClassA的object,但是,在ClassA的object中我有一个ClassB的object属性。这有助于我保留ClassB的对象,直到其异步方法完成
问题:当我在主线程上运行以下代码时,它运行正常,但当我将长时间运行的方法放在异步线程中时,objectB立即被解除分配,并且什么也没有发生Ios 如何在另一个对象中保留运行异步任务的对象并成功运行异步任务? 我分别有两个类A和类B的对象 ClassB包含一个很大的方法,我想在后台异步运行它,或者说其他异步线程 我正确地保留了ClassA的object,但是,在ClassA的object中我有一个ClassB的object属性。这有助于我保留ClassB的对象,直到其异步方法完成,ios,objective-c,asynchronous,objective-c-blocks,Ios,Objective C,Asynchronous,Objective C Blocks,问题:当我在主线程上运行以下代码时,它运行正常,但当我将长时间运行的方法放在异步线程中时,objectB立即被解除分配,并且什么也没有发生 @interface ClassA : NSObject @property(nonatomic, strong) ClassB *objB; @implementation ClassA -(void)createAndExecuteB { self.objB = [ClassB getNewAndExecute]; }
@interface ClassA : NSObject
@property(nonatomic, strong) ClassB *objB;
@implementation ClassA
-(void)createAndExecuteB
{
self.objB = [ClassB getNewAndExecute];
}
@interface ClassB
+(ClassB *)getNewAndExecute;
@end
@implementation ClassB
-(void)timeConsumingTask
{
//statements
}
+(ClassB *)getNewAndExecute
{
ClassB * __block objB = [[ClassB alloc] init];
//Here is my issue. If I remove this dispatch code and just call
// the timeConsumingTask method, then everything works well (blocking
// the UI thread for a while but completing the tasks properly).
// but if I keep the dispatch code, then this object gets instantly
// deallocated and nothing runs
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0) ,^{
[objB timeConsumingTask];
});
return objB;
}
@end
此代码应该可以正常工作,所以问题一定出在您没有告诉我们的地方 你可能是
[ClassB getNewAndExecute]
,而不是通过[classA createAndExecuteB]
李>
classA
实例上多次调用[classA createAndExecuteB]
,这将覆盖您试图保留的self.classB
timeConsumingTask
结束时发生的情况。ClassA
或保留ClassA
的任何东西如何知道timeConsumingTask
已完成?这是您必须释放ClassB
实例的时间,因此它很重要
检查1应该很容易
要选中2,请将dealloc
方法添加到ClassA
和ClassB
中,并添加NSLog
语句或在它们上设置断点,以便您可以看到对象何时被解除分配
要选中3,请在createAndExecuteB
中添加一个NSLog
,以便查看您接到的电话数量
这是一个很好的技巧,可以打印对象的指针,这样您就可以看到您是否无意中使用了实例:
NSLog(@"%p %p", (void *)self, (void *)self.classB);
为什么要使用uu块?我使用了u块,这样可以从dispatch async的void块修改objB变量,还可以调用方法“timeConsumingTask”@CodenameLambda1,但您没有在块内修改
objB
,因此没有理由使用\uu块
。如果在块内执行类似于objB=…
的操作,则需要\uu块
。@CodenameLambda1 objB变量是指针-它不会在块中修改(至少不应该修改)。如果修改objB的属性,就不需要将其标记为_block,我知道,但是我在实际代码中从异步块设置了对objB的某些更改,因此,我在这里保留了相同的设置。需要注意的是,即使不保留_块,也会导致相同的即时释放行为。但是,是的,我在ClassB中添加了dealloc方法,它会立即打印出来。不会多次运行这些方法。objB正确保留。如您所见,如果我只是删除dispatch_async,那么一切都会运行得很好。但是,我放置了dispatch_async,这样就不会阻塞UI线程。在ObjB中,还有一个NSI通知,我会触发,objA会监听。我通过调用dispatch_get_main_队列在timeConsumingTask之后触发通知。:)@代码名lambda1您是否检查了classA是否按照2中的建议正确保留?是的,Peter,它被保留了。基本上在我的实际代码中,classA是一个单例。因此,它贯穿整个应用程序。:)