Objective-Cのループコンテナー

しばらく前に、私はこのコードを書きました:



NSMutableArray *environments = [NSMutableArray new]; for (NSString *key in [dictionary allKeys]) { XCCEnvironment *environment = [[XCCEnvironment alloc] initWithName:key parameters:dictionary[key]]; [environments addObject:environments]; } return environments;
      
      





問題に気づきましたか? しません。



問題



プログラムを開始した後、クラッシュしました。



 [__NSArrayM someSelector]: unrecognized selector sent to instance 0x100211d80
      
      





「環境」ハンドラーは「XCCEnvironment」を予期していましたが、「NSMutableArray」を受け取りました。



最初はなぜこれが起こったのかは明確ではありませんでしたが、コードを見ると、同じ配列に配列を配置しただけでした。



 // ... NSMutableArray *environments = [NSMutableArray new]; // ... [environments addObject:environments]; // ...
      
      





ドキュメントでは、このような状況でのコレクションの動作については何も言及していません。このテーマで見つけた唯一の有用な資料は、Mike Ashの記事です。Cocoaを破壊しましょう



この記事では、いわゆる循環コンテナーを作成すると、可変配列、辞書、およびセットがおかしくなると主張しています。 また、ARCが有効になっている場合、メモリリークが発生します-コレクションは保持されます。



解決策



通常、開発者は自分の内部にコレクションを配置しません。 これは、プログラマーがNULLポインターを逆参照しないという主張と同じです。これはまだ発生しており、おそらくプログラマーが期待するものではありません。



clangはこのエラーを防ぐことができると確信していましたが、このチェックを含むパラメーター/設定は見つかりませんでした。



最後に、このチェックを追加することにしました。 実装には数晩かかりましたが、現在はトランク内にあります



パッチには、次のコレクションのチェックが含まれます。





それ自体にコレクションを追加しようとすると警告が表示されます。

それはデフォルトで有効になっていても、それぞれ - 「WNO-にObjC円形コンテナ」、警告が旗「-wobjc円形コンテナ」/によってオン/オフにすることができます。



おわりに



trunkのclangバージョンにはこの機能が含まれていますが、Xcodeではまだ利用できません。次のメジャーリリース後、おそらく1年後にそこに表示されると思います。



それはそうかもしれませんが、オープンソースのコンパイラを持っていることは素晴らしいことです。あなたはそれを修正し、改善し、あなたの人生と他の人々の人生を少し楽にすることができます。



ハッピーハッキング!



All Articles