【发布时间】:2012-12-17 05:57:28
【问题描述】:
我有点吃不消了。我知道从一个块中调用 [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] 的情况下工作,但是 super 会被保留、正确释放等吗?是的,我正在使用 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);
}
我希望这可以避免任何保留周期,尽管我还没有真正对其进行分析。
【问题讨论】:
-
为什么不能只声明一个指向超类的weakSelf 指针?你知道吗,比如
__weak __block NSObject *weakSuper = self;? -
这是一个有趣的想法,让我测试一下。
-
不,它不起作用,由于某种原因,继承的方法被调用,而不是来自超类的方法。似乎只有 [super method] 将调用委托给正确的类。除非我做错了。
-
CodaFi 的评论有错字,应该是:
__weak __block NSObject *weakSuper = super; -
@AndrewTetlaw:不,
super在 Objective-C 中不是一个有效的表达式(与大多数其他 OO 语言一样,例如 Java)。它只能用在消息调用表达式的左侧。
标签: objective-c objective-c-blocks superclass method-hiding retain-cycle