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