【问题标题】:Is this safe to set property inside a block在块内设置属性是否安全
【发布时间】:2015-01-12 06:19:21
【问题描述】:

我是 iOS 8 的 Objective-C 新手,所以对 ARC 有点了解,我的代码在 ARC 下。

假设我有一个类 UserModel 具有 NSArray 和 NSString 等属性。我有 initWithDataSource:data 来分配初始化 UserModel。

从内存的角度来看,在块内设置属性是否安全?我觉得我的代码会导致任何保留周期。想知道我应该使用弱自我之类的东西还是其他东西来设置属性?

//在HomeViewController.m中

@interface HomeViewController() <UICollectionViewDataSource>
@property (strong, nonatomic) IBOutlet UILabel *HomeLabel;
@property (strong, nonatomic) IBOutlet UICollectionView *ProjectCollectionView;
@property (strong, nonatomic) UserModel * HomeViewUserModel;
@end


/**
 *  fetch latest projects from remote side
 */
- (void) fetchUserModelFromRemote {
    [MySharedInstance getProjectDataOnSuccess:^(id result) {

        NSDictionary *data = result[@"data"];
        self.HomeViewUserModel = [[UserModel alloc] initWithDataSource:data];

        [[NSNotificationCenter defaultCenter] postNotificationName:@"alertCountUpdate" object:self userInfo:@{@"count": (NSNumber *)data[@"unread"]}];

    }onFailure:^(id error) {}];

    [MyCache cacheProjectListWithData:self.HomeViewUserModel];
}

【问题讨论】:

  • 我觉得有一个retain循环,因为我在一个块内访问self,所以我应该使用weak self。是否有任何最佳实践来设置属性 insisde 块?

标签: ios objective-c


【解决方案1】:

如果self 保留对其访问的块的引用,这应该是一个问题。但是如果您想安全起见,就在块之外,您可以将 self 类型的弱变量分配给 self,这样您正在访问一个弱版本的 self 以消除任何疑问,例如:

__weak TypeOfSelf weakSelf = self;

//use weakSelf in block

还可以添加一些 nil 检查以确保在对其进行任何操作之前它仍然存在

【讨论】:

  • 如何判断 self 是否保留了对块的引用?
  • 好吧,在这种情况下你不是,但如果你在HomeViewController 中实现了一个保留对块的引用的属性,那么 self 将具有对块的引用,并且块将具有引用对自己。但也许单身MySharedInstance 永远不会放开障碍,这也会导致问题
  • but maybe the singleton MySharedInstance doesnt let go of the block ever, and that would also cause an issue 这正是我认为这里正在发生的事情。
  • 这不是关于“安全”与否的问题。在 OP 的示例中,没有保留周期,使用 weak 并不能使其更安全。但是,当使用弱引用时,处理程序的 逻辑语义 会发生变化。您可能只想选择 weak 以防止块保留引用,以便在块完成之前 可以 销毁对象。同样,您可能希望选择一个强引用来防止对象在块被执行之前被销毁。
  • 但是有人告诉我使用弱 self 是一个好习惯,即使在这种情况下,self 不在屏幕上时可能会得到 dealloc 或其他东西(因为它是一个视图控制器) ,但该块可能会保持这个自我,直到它从互联网上获取一些数据并返回。
【解决方案2】:

您的担忧是有效的,但没有保留周期:

self 本身不会引用匿名块 - 因此,没有循环引用。

另见:Using weak self in dispatch_async function

【讨论】:

  • 如何判断是不是匿名块?
  • @Wingzero 当您以与在示例中定义完成处理程序相同的方式定义块 inline 时,您的代码中没有引用此块的变量。但是,您可以拥有引用块的类的属性。然后,某个客户端可能会为该类的实例分配一个块,self 可以调用该块。在这种情况下,自引用块。然后,当这个块引用self 时,是的,你会得到一个保留周期。
猜你喜欢
  • 2013-12-28
  • 1970-01-01
  • 2016-01-06
  • 1970-01-01
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-13
相关资源
最近更新 更多