gpt4 book ai didi

objective-c - 类和 block 的生命周期

转载 作者:行者123 更新时间:2023-12-01 16:54:41 25 4
gpt4 key购买 nike

当一个由 UIViewController 创建的类作为另一个类的完成 block 时,当 UIViewController 得到一个 dealloc 调用时,内存管理生命周期如何工作?

假设 UIViewController 继承类实例化了一个类,ControllerMediatorClass。

ControllerMediatorClass 反过来调用另一个类 ClassThatDealsWithNetworking,它的工作需要一些时间才能完成。

如果 UIViewController 在 ClassThatDealsWithNetworking 完成之前得到它的 dealloc,那么它所拥有的类什么时候会被清理掉?

当 MyUIViewController 将它设置为 nil 时,'ControllerMediatorClass' 的实例是否不会立即被释放,因为 ControllerMediatorClass 仍然充当 ClassThatDealsWithNetworking 实例的完成 block ?

我的UIViewController:

@property (nonatomic, strong) ControllerMediatorClass *mediatorClass;

- (IBAction)userTappedSomething
{
[mediatorClass makeANetworkCall];
}

- (void)dealloc
{
self.mediatorClass = nil;
}

Controller 中介类:
- (void)makeANetworkCall
{
ClassThatDealsWithNetworking *networkCommand;

[networkCommand execute:^(NSDictionary *data)
{
// handling completion that
} error:^(MyError *error)
{
// handling completion
}
];
}

(使用 ARC)

最佳答案

Would the instance of 'ControllerMediatorClass' not get deallocated immediately when MyUIViewController sets it to nil because ControllerMediatorClass still serves as a completion block to the instance of ClassThatDealsWithNetworking?



是的。因为 block 会自动捕获它使用的对象,并在保留 block 时保留它们。

所以,作为 [ClassThatDealsWithNetworking execute:]方法可能会保留传递给它的完成 block ,然后在后台执行网络调用,然后在完成后调用该 block 并释放该 block ,当该 block 被保留时,该 block 中使用的每个变量也被保留。并且会在 block 被释放时被释放。

所以想象一下你的 ClassThatDealsWithNetworking 的这个伪代码类(class):
typedef void(^NetworkingCompletionBlock)(NSDictionary* data)
@interface ClassThatDealsWithNetworking
@property(nonatomic, copy) NetworkingCompletionBlock completionBlock;
-(void)execute:(NetworkingCompletionBlock)block;
@end

@implementation ClassThatDealsWithNetworking
-(void)execute:(NetworkingCompletionBlock)block {
// make a copy of the block passed as a parameter
// so that we keep the completionBlock around inside
// the ClassThatDealsWithNetworking instance
// until the network request has finished
// ==> THIS WILL implicitly RETAIN every object used in the completionBlock
self.completionBlock = block;
...
// Then perform the network request
[NSURLConnection connectionWithRequest:... delegate:self];
...
}

-(void)connection:(NSURLConnection*)cxn didFailWithError:(NSError*)error
{
// call the completion block here
self.completionBlock(nil,error);
// then release the completionBlock
// ==> THIS WILL RELEASE every object previously implicitly retained by the completionBlock
self.completionBlock = nil;
}
-(void)connectionDidFinishLoading:(NSURLConnection*)cxn
{
NSDictionary* data = ...
// call the completion block here
self.completionBlock(data,nil);
// then release the completionBlock
// ==> THIS WILL RELEASE every object previously implicitly retained by the completionBlock
self.completionBlock = nil;
}
@end

然后,如果你这样做:
[networkCommand execute:^(NSDictionary *data) 
{
self.someProperty = data;
} error:^(MyError *error)
{
NSLog(@"%@", error);
self.someProperty : nil;
}];

然后 self (您的 ControllerMediatorClass 在您的示例中) 将被 block 隐式保留本身,只要 block 存在,因为您的引用 self在 block 体的某处。所以编译器知道在执行 block 时它会需要它并保留它。它 释放 block 时会隐式释放 .

这确保了您在 block 体中使用的所有对象在 block 执行时仍然存在,避免崩溃。

请注意,如果您不小心,这可能会导致保留周期。例如,如果您忘记自我 self.completionBlock = nilClassThatDealsWithNetworking类(在委托(delegate)方法或 dealloc 方法中), block 将永远不会被 ClassThatDealsWithNetworking 释放实例,并将继续保留 self .

欲了解更多信息,请阅读 Blocks Programming Guide在 Apple 文档中。

关于objective-c - 类和 block 的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12712343/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com