Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa touch 是否有必要使用弱引用来始终位于块内的self。。?_Cocoa Touch_Cocoa_Objective C Blocks - Fatal编程技术网

Cocoa touch 是否有必要使用弱引用来始终位于块内的self。。?

Cocoa touch 是否有必要使用弱引用来始终位于块内的self。。?,cocoa-touch,cocoa,objective-c-blocks,Cocoa Touch,Cocoa,Objective C Blocks,我对self-inside块的使用感到困惑,我浏览了一些苹果的文档,但仍然找不到正确的答案 有些人总是说在块中使用弱自我,但有些人说在复制的块中使用弱自我,而不是总是必须使用 样本1: self.handler = ^(id response, NSError *error) { self.newresponse = response; //use weak self here }; 样本2: 利用弱自我 __weak myViewController *weakSelf = se

我对self-inside块的使用感到困惑,我浏览了一些苹果的文档,但仍然找不到正确的答案

有些人总是说在块中使用弱自我,但有些人说在复制的块中使用弱自我,而不是总是必须使用

样本1:

self.handler = ^(id response, NSError *error)
{
    self.newresponse = response; //use weak self here
};  
样本2:

利用弱自我

__weak myViewController *weakSelf = self;

[UIView animateWithDuration:interval delay:0.0 options:curve animations:^
{
    [weakSelf.view.superview setTransform:CGAffineTransformMakeTranslation(0, -106)];
    //in above is it use of weak is neassary 
}
completion:^(BOOL finished)
{

}];
__weak myViewController *weakSelf = self;

[UIView animateWithDuration:interval delay:0.0 options:curve animations:^
{
    [myViewController.view.superview setTransform:CGAffineTransformMakeTranslation(0, -106)];

}
completion:^(BOOL finished)
{

}];
没有软弱的自我

__weak myViewController *weakSelf = self;

[UIView animateWithDuration:interval delay:0.0 options:curve animations:^
{
    [weakSelf.view.superview setTransform:CGAffineTransformMakeTranslation(0, -106)];
    //in above is it use of weak is neassary 
}
completion:^(BOOL finished)
{

}];
__weak myViewController *weakSelf = self;

[UIView animateWithDuration:interval delay:0.0 options:curve animations:^
{
    [myViewController.view.superview setTransform:CGAffineTransformMakeTranslation(0, -106)];

}
completion:^(BOOL finished)
{

}];
在上述样本中,哪些是正确的…?
**我使用的是ARC

如果
self
将保留块的引用,则只应使用对
self
的弱引用

在您的示例中,您没有在
self
中保留对块的引用,您只使用与
UIView animateWithDuration:
内联的块,因此无需使用
\uu弱myViewController*weakSelf=self


为什么会这样?因为块将保留对使用该块的类中它使用的任何变量的强引用。这包括
self
。现在,如果类实例本身保持对该块的强引用,而该块保持对该类实例的强引用,则存在一个保留周期,这将导致内存泄漏。

以下是一些代码,演示@WDUK的答案:

typedef void (^SimpleBlock)();

@interface ObjectThatRetainsBlock : NSObject
@property(nonatomic, strong) SimpleBlock block;
@end

@implementation ObjectThatRetainsBlock

- (instancetype)init {
  self = [super init];
  if (self) {
    self.block = ^{ NSLog(@"Running block in %@", self); };
    self.block();
  }
  return self;
}

- (void)dealloc {
  NSLog(@"ObjectThatRetainsBlock is deallocated.");
}

@end

@interface ObjectThatDoesNotRetainBlock : NSObject
@end

@implementation ObjectThatDoesNotRetainBlock

- (instancetype)init {
  self = [super init];
  if (self) {
    SimpleBlock block = ^{ NSLog(@"Running block in %@", self); };
    block();
  }
  return self;
}

- (void)dealloc {
  NSLog(@"ObjectThatDoesNotRetainBlock is deallocated.");
}

@end

- (void)test {
  ObjectThatRetainsBlock *objectThatRetainsBlock =
      [[ObjectThatRetainsBlock alloc] init];
  ObjectThatDoesNotRetainBlock *objectThatDoesNotRetainBlock = 
      [[ObjectThatDoesNotRetainBlock alloc] init];
}
测试方法打印:

Running block in <ObjectThatRetainsBlock: 0x7f95f3335e50>
Running block in <ObjectThatDoesNotRetainBlock: 0x7f95f3335c50>
ObjectThatDoesNotRetainBlock is deallocated.
运行块插入
运行阻塞
释放不包含块的对象。
请注意,在不包含块的
对象的
init
方法中,我们将
block
创建为ivar,但当
超出范围时,我们不会保留对它的引用

test
方法中,当两个对象超出范围时,观察不包含块的
对象被解除分配,因为它不是保留周期的一部分

另一方面,
objectthatRetainBlock
不会被释放,因为它是保留周期的一部分。它将块保留在方法调用的范围之外


如果您需要另一种解释,请参阅。

可能的类内方法(animateWithDuration)的副本也不需要弱self,因为self没有保留或拥有该块,对吗…?在示例1中self.handler=^(id response,NSError*error){self.newresponse=response;//在此处使用弱self};我们需要一周的self,因为block被self保留,self被block保留,所以它是保留循环…?@jeeva在样本1中,需要一个self的弱引用。在示例2和3中,不需要对self进行弱引用。谢谢,您的解释完全有道理。然而,我无法解释在苹果的示例代码中使用
weakSelf
:一个好的观点,我忽略了
self
没有保留块的事实;它只是对框架的回调。道歉。我相信在这种情况下,这是一种防御编码。声明它弱没有什么坏处,因为从概念上讲,在这里保留
self
是没有意义的(为什么回调应该延长
self
?)。这也意味着,如果有人想稍后存储块,他们不需要更改其内容。最终,虽然在这里声明它弱不是防止泄漏所必需的,但它是一些程序员用来确保健壮性的一种方式。