Ios 弱自用和强自用,阻止内存管理

Ios 弱自用和强自用,阻止内存管理,ios,objective-c,memory-management,objective-c-blocks,Ios,Objective C,Memory Management,Objective C Blocks,关于这些软弱和坚强的自我有很多问题,但我想让你们看看我的例子: - (void)getItemsWithCompletionHandler:(void (^)(NSArray*items))completionHandler { __weak __typeof__(self) weakSelf = self; [self doWorkWithCompletionHandler:^(Response *response) { // this completion is not on

关于这些软弱和坚强的自我有很多问题,但我想让你们看看我的例子:

- (void)getItemsWithCompletionHandler:(void (^)(NSArray*items))completionHandler {
 __weak __typeof__(self) weakSelf = self;
 [self doWorkWithCompletionHandler:^(Response *response) {
     // this completion is not on main thread
     dispatch_async(dispatch_get_main_queue(), ^{
         ...
         [weakSelf doAnotherWorkWithCompletionHandler:^(Response *response) {
             // this completions is not on main thread either
             dispatch_async(dispatch_get_main_queue(), ^{
                 __typeof__(self) strongSelf = weakSelf;
                 NSArray *itemsIds = [strongSelf doWorkOnMainThread1];
                 NSArray *items = [strongSelf doWorkOnMainThread2];
                 completionHandler(items);
             });
         }]; 
     });
 }];
}

这里一切都对吗?另外,欢迎您建议重构

您应该检查completionHandler是否不为NULL,然后调用它

if (completionHandler) {
  completionHandler(items);
}
否则,如果completionHandler为NULL,您将崩溃


如果在任何时候
self==nil
,您还可以重新考虑是否要调用
completionHandler(items)
。我这么说是因为有一点不一致。
一致

如果weakSelf已经为nil,则不会调用它的
completionHandler
,并且在结果中也不会调用
completionHandler(items)

但在这里:

__typeof__(self) strongSelf = weakSelf;
NSArray *itemsIds = [strongSelf doWorkOnMainThread1];
NSArray *items = [strongSelf doWorkOnMainThread2];
completionHandler(items);
如果
self==nil
,那么实际上将调用
completionHandler

当然,我看不到整个情况,也许这完全不相关,但你可能需要考虑一些事情

更进一步,我假设您宁愿在每个场景中调用
completionHandler
,即使在任何时候
self==nil
。或者在出现任何错误时向其添加错误参数


如果你想变得超级学究,你可能想在类型后面加上uu弱,例如:

__typeof__(self) __weak weakSelf = self;

这是首选的方法:(寻找“您应该正确地修饰变量”。

如果您打开所有警告,那么您将收到一个警告

[weakSelf doAnotherWorkWithCompletionHandler... ];
您不应该向弱对象发送消息。当调用的方法正在运行时,弱对象可能会消失。将弱对象存储到强对象中,结果要么为零,要么不是。如果你打电话

[strongSelf doAnotherWorkWithCompletionHandler... ];

您知道strongSelf==nil且不发生任何事情,或者strongSelf在方法执行时为且保持为非nil

这个问题可以根据在外部局部范围中声明
itemsid
items
的意义进行更好的分类?在异步操作中分配这两个变量时,作用域不会存在。是什么让你认为这里需要弱引用?问题主要是关于块内存管理,而不是重构!
[strongSelf doAnotherWorkWithCompletionHandler... ];