2016-12-17 6 views
1

問題を解決する方法を見つけましたが、なぜ機能しないのか理解したいのですが、意味が分かりません。私は住所をジオコーディングするCoreLocationを使用して、簡単なtodolistのアプリケーションを開発するために本を、次のよCLPlacemarkを拡張するときのEXC_BAD_ACCESS - 定義スコープ外の変数にアクセスしました

import XCTest 
import CoreLocation 

class ExampleTests: XCTestCase { 

    var okay: ext! 

    // this test works fine 
    func testOkay(){ 
     okay = ext() 
     XCTAssertNotNil(okay) 
    } 

    // this test crashes with EXC_BAD_ACCESS(code=1, address=0x10) 
    func testNotOkay(){ 
     let notOkay: ext 
     notOkay = ext() 
     XCTAssertNotNil(notOkay) 
    } 
} 

extension ExampleTests { 
    class ext : CLPlacemark{ 

    } 
} 

:ここに私の問題を示して最小限の例です。テストの一環として、ジオコーディング機能をテストするための模擬CLPlacemarkオブジェクトを作成する必要がありました。

にはがありました。そうでなければ "テストはその定義スコープの外でアクセスされているのでテストがクラッシュする"ため、このモックの変数をTestクラスのプロパティとして宣言すると言われました。

これは、上記の例で確認できます。 okayがクラスプロパティとして宣言されたため、testOkay()は正常に動作します。 testNotOkay()EXC_BAD_ACCESSエラーでクラッシュします。これは、関数内でextの新しいインスタンスをインスタンス化しようとしたためです。私はCLPlacemarkを拡張しない場合

さて、問題は消える - すなわち私は関数の中で、あるいはまったく問題にクラスのプロパティとしてタイプextの変数を宣言することができます。

ここでは何が起こっていますか?最初のものが動作している間に2番目の例がクラッシュする理由はありません。実際のコードでは、1つまたは2つの関数でのみ使用されている場合、クラスのプロパティとして擬似目印インスタンスを宣言することは些細なことです。この問題を引き起こしているスウィフトについて私が理解していないものがなければならない。

ありがとうございます!

答えて

3

私は最近、定義済みのCLPlacemarkインスタンスを入力として提供する必要のある機能をテストする際に、この問題に遭遇しました。いくつかの研究の後、誰かがCLBeaconクラスで同様の問題を抱えていることがわかりました。あなたはまた、明示的に自分でそれらを作成することができますが、

EXC_BAD_ACCESS when setting a CLBeacon to nil

目印オブジェクトは、通常、CLGeocoderオブジェクトによって生成されます。

あなた自身でCLPlacemarkインスタンスを作成できるというAppleの文書にもかかわらず、このクラスは、サブクラス化については素晴らしい人ではありません。インスタンスを作成するときは、というプライベートクラス(nil)に依存します。下の画像では、このオブジェクトがデバッガでどのように見えるかを見ることができます。 _internal ivarの値は0x0であり、これはnilです。

screenshot

クラッシュEXC_BAD_ACCESSメッセージを持つあなたがインスタンス化されたオブジェクトが割り当て解除されます場合に発生します。スコープを外れるか、別のオブジェクト(またはnil)を変数に割り当てるかどうかにかかわらず。なぜそれが起こっているのですか?これはAppleの開発者にとっての質問です。しかし、以下では、他の人が実装した回避策を見つけることができます。

+0

見つけグッド!私はこのことを考え出すことをあきらめた。情報をありがとうございます:)それで、 'testNotOkay'関数が終了した後にインスタンスの割り当てを解除しようとするとクラッシュするようです。 –

関連する問題