7

__weak記憶修飾子をメソッドの実装の署名に使用するのは有効ですか?特にメソッドのパブリックシグネチャの一部でない場合は?例:__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スタティックアナライザは警告をスローしません。

答えて

1

ダイナミックディスパッチが含まれていて、(1)をオーバーライドしているときに、記憶修飾子または属性が「動的に」受け取られることを期待しないでください。

このメソッドは、UIKitで正式に宣言されています。コンパイラは、呼び出されたときにセレクタが元の宣言に一致する可能性があるため、ARCを使用するときに間違ってしまう可能性があります。つまり、あなたの宣言はUIKitには見えません。また、UIKitはARCとしてコンパイルされていると、それをdefault/strongとして扱います。これは、宣言が一致しない場合や、クライアント+呼び出し元の翻訳で表示されない場合でも発生します。

パラメータタイプ/属性はセレクタの一部ではなく、動的にディスパッチするためにも適用されません。 ARCはここで強く想定し、発信者には参照が保持されている必要があります。この具体的な例ではランタイムエラーは発生しないかもしれませんが、疑わしい習慣でエラーを見つけることができます。私は属性in this answerのためにこれを証明しました。基本的には同様の概念です。

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

(1)技術的には、オーバーライドではなく、プロトコルのメソッドの実装です。関係なく、sigは同一でなければなりません。

0

__strongまたは__weak記憶修飾子は、私が見る限り、内部実装の一部です。メソッドの呼び出し元によって生成されたコードには影響しません。したがって、現在安全であり、将来は非常に可能性が高いと思います。

私はそれが貧弱なスタイルだと思います。そのため、リファレンスを弱参照にコピーすることをお勧めします。