私は少し漬け物になっています。ブロック内から[selfmethodName]を呼び出すと、保持サイクルが発生することを知っています。
ただし、このクラスではマルチスレッドが原因で、ブロックがアクセスしているメソッドをブロック以外の場所から実行することを許可できません。重大な問題が発生する可能性があるためです。
現在のコード:
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;
};
}
まさにそれを行い、[selfgetmethod]を呼び出します。ディスパッチされたブロックがこのメソッドを実行することは問題ありませんが、このクラスの外部でこのメソッドを呼び出すことは望ましくありません。したがって、この継承されたメソッドをそのままオーバーライドしても問題ありません。
- (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を使用し、プロファイルを作成して、保持サイクルにつながるかどうかを確認します。
編集#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);
}
実際にはまだプロファイルを作成していませんが、これによって保持サイクルが回避されることを期待しています。