7

__weakメソッドの実装の署名でストレージ修飾子を使用することは有効ですか? 特に、それがメソッドの公開署名の一部でない場合は? 例えば:

- (UIView *)tableView:(__weak UITableView *)tableView viewForHeaderInSection:(NSInteger)sectionIndex
{
    UIView *view = [ABHeaderView view];
    view.actionBlock = ^{
        [tableView doSomething];
    }
    // ...
    return view;
}

これは正しくtableViewウィーク ポインターとして使用されますか? それとも、本当にブロック内で何かを__weak *weakTableView = tableView;して使用する必要がありますか?weakTableView

警告やエラーは表示されず、clang Static Analyzer は警告をスローしません。

4

2 に答える 2

1

動的ディスパッチが含まれ、オーバーライドする場合、ストレージ修飾子または属性が「動的に」尊重されることを期待しないでください(1)。

このメソッドはUIKitで正式に宣言されています。ARCを使用すると、呼び出されたときにセレクターが元の宣言と一致する可能性があるため、コンパイラーが間違っている可能性があります。つまり、宣言はUIKitには表示されません。また、ARCとしてコンパイルされている場合、UIKitはそれをデフォルト/ストロングとして扱います。これは、宣言が一致しない場合、またはクライアントと発信者の変換に表示されない場合でも発生する可能性があります。

パラメータタイプ/属性はセレクタの一部ではなく、動的にディスパッチするために適用されることもありません。ARCはここで強力であり、呼び出し元が参照を保持していると想定する必要があります。この特定の例ではランタイムエラーが発生しない可能性がありますが、エラーが見つかる可能性があると私が想定しているのは疑わしい方法です。私はこの回答の属性についてこれを証明しました。基本的に、それは同様の概念です。

動的objcディスパッチを使用した単純なルール:再宣言、定義、およびオーバーライドするときは、常に元の宣言の署名と一致します。唯一の例外は、署名を変更しないC互換の修飾子の場合です(私が見たObjCプログラムでは非常に一般的ではありません)

(1)技術的には、これはオーバーライドではなく、プロトコルのメソッドの実装です。とにかく、sigは同一である必要があります。

于 2012-04-17T12:59:07.673 に答える
0

__strongまたは__weakストレージ修飾子は、私が見る限り、内部実装の一部です。それらはメソッドの呼び出し元によって生成されたコードに影響を与えないので、今は安全であり、将来も安全である可能性が高いと思います.

ただし、スタイルが悪いと思うので、参照を弱い参照にコピーするという提案は良い解決策のようです。

于 2012-04-17T11:19:39.937 に答える