从Objective-C Block访问assign delegate属性? (IOS)

时间:2012-02-24 09:38:06

标签: ios ios4 objective-c-blocks

可以从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;
}

2 个答案:

答案 0 :(得分:3)

通常,如果在执行块之前取消分配delegate,那么它将访问垃圾,因为该块是assign属性,并且块保留self而不是delegate {1}}因为您通过引用访问它。

但是,由于您已将其设置为self.delegate,因此如果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

答案 1 :(得分:0)

如果代理被取消分配,您将访问垃圾值,这将导致EXC_BAD_ACCESS

你可以做

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

或直接访问ivar,以便块保留它

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