【问题标题】:Access a assign delegate property from Objective-C Block? (iOS)从 Objective-C 块访问分配委托属性? (iOS)
【发布时间】:2012-02-24 09:38:05
【问题描述】:

可以从 Block 访问委托属性吗?

@interface TheObject : NSObject
...
@property (nonatomic, assign) id<SomeDelegate> delegate;

@synthesize delegate

- (void) someMethod {
  [someObject doSomethingWithCompletionHandler:^(NSArray *)someArray {
      [self.delegate otherMethod:someArray];   
 }];
}

如果委托在调用完成处理程序之前被取消(从也设置委托的对象中的 dealloc 方法)会发生什么? 会不会是内存错误? 我不知道如何将__block 用于属性...

从下面回答:

如果委托是从作为 dealloc 调用的委托的对象中删除的,那么一切都很好。

@property (nonatomic, retain) TheObject theObject;

@synthezise theObject = _theObject;

- (void) thatMethod {
  self.theObject = [[TheObject alloc] init] autorelease];
  _theObject.delegate = self;
}

- (void) dealloc {
  _theObject.delegate = nil;
  self.theObject = nil;
}

【问题讨论】:

    标签: ios ios4 objective-c-blocks


    【解决方案1】:

    通常,如果您的 delegate 在块执行之前被释放,那么它会访问垃圾,因为块是 assign 属性并且块保留 self 而不是 delegate 因为您访问它参考。

    但是,由于您已将其设置为如果 delegate 被释放,则 self.delegate 将变为空,因此您不会遇到这个问题。相反,如果您的 delegate 被释放,那么在您的代码中,您只需将 otherMethod: 方法发送到 nil,这不会做任何事情,但也不会导致错误。

    如果您希望该方法绝对发送到您的delegate,则解决方案是通过值而不是引用来访问它:

    - (void)someMethod {
        id <SomeDelegate> delegateForBlock = self.delegate;
        [someObject doSomethingWithCompletionHandler:^(NSArray *)someArray {
            [delegateForBlock otherMethod:someArray];   
        }];
    }
    

    这样delegateForBlock 将是指向与self.delegate 相同的对象的指针(在您执行someMethod: 时),它将被保留。

    要了解有关其工作原理的更多信息,请查看Blocks Programming Topics

    【讨论】:

    • 知道如何解决这个问题吗?并且:如果委托对象被解除分配,则委托 ivar 在 dealloc 中从此对象中被取消。也在街区里?
    • 好的,请参阅更新的答案。此外,您应该编辑您的问题顶部,说明您如何将指针设置为 nilled,因为它有很大的不同。
    【解决方案2】:

    如果委托被解除分配,您将访问一个垃圾值,这将导致EXC_BAD_ACCESS

    你可以这样做

    id <SomeDelegate> dlg = self.delegate
    [someObject doSomethingWithCompletionHandler:^(NSArray *)someArray {
      [dlg otherMethod:someArray];   
    }];
    

    或者直接访问ivar,让block保留它

    [someObject doSomethingWithCompletionHandler:^(NSArray *)someArray {
      [delegate otherMethod:someArray];   
    }];
    

    【讨论】:

    • 最好检查您的事实...“如果您按值访问实例变量,则保留该变量。”
    • 我对你的帖子做了一个简单的编辑,所以我可以取消投票。我真诚地希望您不是对我的答案投反对票的人,除非您认为它有问题(在这种情况下,如果您能对此发表评论,那就太好了)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    • 2016-10-30
    • 2019-12-27
    • 2015-09-02
    相关资源
    最近更新 更多