2013-07-22 5 views
6

です。コードベースでいくつかのClangエラーを解決する任務がありました。私はiPhoneの開発とObjective Cについては非常に新しいですが、問題のほとんどが些細なことを発見しました。この1つは、私が何か困惑していると確信しているときに私を突き飛ばしています。Objective-C: 'self'が設定されていないのにインスタンス変数が使用されていますが、それは

ZAttributedStringクラスから:

- (id)initWithAttributedString:(ZAttributedString *)attr { 
    NSParameterAssert(attr != nil); 
    if ((self = [super init])) { 
     _buffer = [attr->_buffer mutableCopy]; 
     _attributes = [[NSMutableArray alloc] initWithArray:attr->_attributes copyItems:YES]; 
    } 
    return self; 
} 

打ち鳴らす警告は「『自己』が結果に設定されていない状態で使用インスタンス変数である 『[superまたは自己]のinit ...]』、とATTRの_buffer属性の逆参照がハイライトされて

それが助け場合

は、警告も、このメソッドから呼び出すときに問題が発見されていることを言及しているようだ:。

- (id)copyWithZone(NSZone *)zone { 
    return [(ZAttributedString *)[ZAttributedString allocWithZone:zone] initWithAttributedString:self]; 
} 

缶誰も私に説明してください正確にここに欠陥が何ですか?

TIA!

答えて

4

インスタンス変数にアクセスするために->を使用しないでください。特には他のオブジェクトからのものです。

_buffer = [[attr string] mutableCopy]; 

同じことがその厄介なattr->_attributesのために行く:

はこれを行います。明らかに、ZAttributedString exposesアトリビュートをプライベートヘッダのプロパティとして使用します。


このコンパイラの警告は、非常に楽観的で、完全に誤解を招きやすく、おそらくかなり記述が間違っているようです。それを明らかにしたバグを書いておくと便利です。それはコピーコンストラクタのような役割を果たして->を使用すると、渡されたattr文字列で直接インスタンス変数にアクセスすること@マディの主張が間違っていることを


注意。

着信attr本当にZAttributedStringインスタンスまたはサブクラスのインスタンスまたは、ZAttributedStringと同じインタフェースを実装するクラスのインスタンスであってもよいです。したがって、あなたは実際にが正しい状態をつかんでいることを保証するためにアクセサを通過する必要があります。

は今、実装の詳細として、ZAttributedStringインバウンドインスタンスがZAttributedStringの非サブクラスのインスタンスであることを必要とする可能性があるが、それはその要件を主張(と、してください、ということをしない)するisMemberOfClass:を使用する必要があります。

別のオブジェクトからステートを引き出すために直接的なバイナリアクセスが使用される唯一の場所は、copyWithZone:の実装ですが、それは非常に壊れやすく、壊れた振る舞いにつながりません。実際には、copyWithZone:(さまざまなplist互換値クラスの外)は、脆弱性と多くの多くのバグの原因となりました。

+3

実際、このコードは 'ZAttributedString'クラスのものですので、同じクラスの別のインスタンスからivarsにアクセスするには' - > 'を使うのがまったく正しいです。これは基本的に "コピーコンストラクタ"を作成しているときにそのようなコードに適しています。 – rmaddy

+1

この場合でも実際は正しくありません。 *それが '-copy'メソッドそのものだった場合、*多分*(ObjCの歴史の中では本当に面白い--NscopyObject()は痛みの終わりをもたらしませんでした)。しかしDIではそうではありません。クラスは、何かを行うゲッターにロジックを持ち、インバインドされたインスタンスは、おそらく未知のビヘイビアを持つサブクラスである可能性があります。 – bbum

+0

@bbum: "着信attrはZAttributedStringインスタンスまたはサブクラスのインスタンスである可能性があります。" self "はサブクラスのインスタンスになる可能性があります。したがって、その引数によってインスタンス変数にアクセスすることはできません。 – user102008

2

"[Bug 15092] New: static analyzer false positive: reports instance variable used while 'self' is not set to the result of [(super or self)] init"とまったく同じバグが表示されているようです。それはバグを再現するために非常に似たコードが付けられています。

Xcode 4.6.3でそのコードを実行すると、表示されているのと同じ誤った警告が出ることを確認できます。

enter image description here

バグがcommentで解決されました:

これはトランクに固定し、または少なくとも大部分が固定されている - いくつかのエッジが警告が発生します 例がまだあります、あなたのプロジェクトではありません。

(現在すべてのアップルでは動作しませんLLVMの人々は、Appleクランへのアクセスを持ってい んアップルで作業を行うので、重複を提出する 本当の必要はありません。メインアナライザエンジニアのためのデイブ、 Xcodeの、そしてこの修正に付属は のXcode 4.6をしなかった。あなたはバグがXcodeの4.6で修正されたが、依然として存在している見ることができるようにあなたも)新しいチェッカーが http://clang-analyzer.llvm.orgから構築する

を得ることができます。 Xcodeの次のバージョンを待つと、アナライザーの警告が消えてしまいます。

+0

llvmのバグを追跡していただき、ありがとうございます。有用! – bbum