我有点苦恼。我知道从块中调用 [self methodName] 将导致保留周期。
然而,在这个类中,由于多线程,我不能允许从块以外的任何其他地方访问块正在访问的方法,因为它可能会导致严重的问题。
当前代码:
if (_getRunning==NO){
__weak SyncArrayMT *_weak_self = self;
_get_t = ^void (void){
_weak_self->_getRunning = YES;
NSArray *objects = [_weak_self get:getQuery
usingClassCtor:ctor
withAuthBlock:authBlock];
if (_weak_self.getBlockCb)
_weak_self.getBlockCb(objects);
_weak_self->_getRunning = NO;
};
}
正是这样做的,它调用[self getmethod]。虽然调度的块可以运行此方法,但我不希望此类之外的任何东西调用此方法。那么,是否可以像这样覆盖这个继承的方法:
- (NSArray *) get:(NSString *)getQuery usingClassCtor:(initBlock)initCb withAuthBlock:(authenticate)authBlock
{
NSLog(@"Direct call to get is not allowed - use the threaded method");
return nil;
}
然后将块更改为:
_get_t = ^void (void){
_weak_self->_getRunning = YES;
NSArray *objects = [super get:getQuery
usingClassCtor:ctor
withAuthBlock:authBlock];
if (_weak_self.getBlockCb)
_weak_self.getBlockCb(objects);
_weak_self->_getRunning = NO;
};
我已经尝试过了,它可以在不调用 [self getMethod] 的情况下工作,但是超级会被保留、正确释放等吗?是的,我正在使用 ARC。在一个块内调用 super 会导致任何问题吗?有没有办法让 __weak 改为 super ?
或者,我怎样才能禁止直接调用 [self getMethod] (它是继承的)并且只在内部使用它?我知道 Objective-C 并没有完全实现这一点,但我知道有一些技巧,比如只在实现文件中声明和实现一个方法。
编辑#1:
我尝试过使用 SEL & IMP 和函数指针。问题是 IMP 和函数指针需要一个实例作为参数,这使得孔点静音:
NSString * (*getFuncPtr)(id,SEL,id,id) = (NSString * (*)(id,SEL,id,id))[super methodForSelector:@selector(sendObjectsPassingTest:withAuthBlock:)];
NSString *reply = getFuncPtr(_weak_self,@selector(sendObjectsPassingTest:withAuthBlock:),predicate,authBlock);
这只是调用继承的方法。尝试将它与 super 一起使用只会产生错误。在这一点上,我将继续并简单地在块内使用 super,并尝试分析它是否会导致任何保留周期。
编辑#2:
根据 newacct 的回答,这就是我最终要做的事情:
typedef NSArray * (* getFuncPtr)(id,SEL,id,id,id);
...
...
__weak SyncArrayMT *_weak_self = self;
_getMethod = (NSArray * (*)(id,SEL,id,id,id))[[[self class] superclass] instanceMethodForSelector:@selector(get:usingClassCtor:withAuthBlock:)];
_get_t = ^void (void){
NSArray *objects = _weak_self->_getMethod(_weak_self,@selector(get:usingClassCtor:withAuthBlock:),getQuery,ctor,authBlock);
}
我希望这应该避免任何保留周期,尽管我还没有真正分析它。