ios - block 不捕获 self
<p><p>我想尝试了解 block 捕获逻辑,但现在我对此有疑问。我有 <code>MeRequest</code> 和 <code>NSNumber</code> 属性。</p>
<pre><code>@property (nonatomic) MeRequest *request;
@property (nonatomic) NSNumber *number;
</code></pre>
<p>然后,在 <code>viewDidLoad</code> 我调用请求方法</p>
<pre><code>self.request = [ init];
[self.request meInfoSuccessBlock:^(NSDictionary *response) {
} failureBlock:^(Error *error) {
self.number = @5;
}];
- (void)meInfoSuccessBlock:(RequestSuccessBlock)success failureBlock:(RequestFailureBlock)failure {
self.method = @"GET";
self.parameters = @{};
[self performWithCompletion:^(id responseObject) {
NSDictionary *response = (NSDictionary *)responseObject;
if (success) {
success(response);
}
} onFailure:^(Error *error) {
if (failure) {
failure(error);
}
}];
}
- (AFHTTPRequestOperation *)performWithCompletion:(void(^)(id responseObject))completion
onFailure:(void(^)(Error *error))failure {
NSURLRequest *request = [ requestWithMethod:self.method path:self.path parameters:self.parameters];
if (_operation) {
;
}
_operation = [ HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
_operation = nil;
dispatch_semaphore_signal(_semaphore);
if (completion) {
completion(responseObject);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
_operation = nil;
dispatch_semaphore_signal(_semaphore);
if (failure) {
failure(_error);
}
}];
;
return _operation;
}
</code></pre>
<p>并且在 <code>failureBlock</code> 我将数字设置为属性。当我离开此 Controller 时,我在控制台中看到了 dealloc 消息,该 Controller 已被释放。</p>
<pre><code>- (void)dealloc {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
</code></pre>
<p>为什么 Controller 会解除分配?我不使用对 <code>self</code></p> 的弱引用</p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>要明确知道,您必须发布 <code>MeRequest</code> 类的实现。 </p>
<p>在不知不觉中,这是一个有根据的猜测。</p>
<p>通过 <code>meInfoSuccessBlock:failureBlock:</code> 传递给 <code>self.request</code> 的 block 在事务完成时可能会被清空。也就是说,它可能是这样的:</p>
<pre><code>- (void)meInfoSuccessBlock:... sB failureBlock:... fB {
_sB = sB; // put ref in ivar
_fB = fB; // because this is probably broken up across methods
dispatch_async(_queue, ^{
.... think hard ...
if (success) _sB(...);
else _fB(...);
_sB = nil;
_fB = nil;
};
}
</code></pre>
<p>所以,首先,您不是在创建直接循环引用,而是——也许——<code>self -> request -> _sB -> self</code> 的循环引用。其次,通过在计算完成并进行回调后分配 <code>_sB = nil</code> 来打破循环。</p>
<hr/>
<p>或者,在您的情况下,您对仅在范围内存在的 block 具有强引用。 IE。有点像这样:</p>
<pre><code>- (void)meInfoSuccessBlock:... sB failureBlock:... fB {
dispatch_async(_queue, ^{
.... think hard ...
if (success) sB(...);
else fB(...);
// when the block finishes execution, fB and sB will be released
};
// when execution gets to here, the block above is the only strong references to sB and fB
}
</code></pre>
<p>也就是说,当您有一个保留循环时,该循环中的一个引用明确地与回调 block 的生命周期相关联,并且由于这些引用仅在回调完成之前存在,它们会被销毁并破坏循环。</p></p>
<p style="font-size: 20px;">关于ios -block 不捕获 self ,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/34555049/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/34555049/
</a>
</p>
页:
[1]