0

このプロジェクトはiOS5.0用です。自動参照カウントを設定しましたが、retainステートメントを記述した場合、とにかくコードをコンパイルできません。

ifと多くのifelseブランチを作成したくないので、関数でスイッチを作成しました。

私のコード部分は比較的単純で正しいように見えますが、次のようにしか見えません。

NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];

switch (selectedRow) {
        
    case 0://English
        [userDefaults setObject:@"English" forKey:@"language"];
        break;
    case 1:// Deutsch 
        [userDefaults setObject:@"German" forKey:@"language"];   
        break;
    case 2://Français
        [userDefaults setObject:@"French" forKey:@"language"];         
        break;
    case 3://Italiano
        [userDefaults setObject:@"Italian" forKey:@"language"];       
        break;
    case 4://Español
        [userDefaults setObject:@"Spanish" forKey:@"language"];
        break;
        
    default:
        break;
}
// flush:
[userDefaults synchronize];

実行時に次のメッセージが表示されました。***-[MyClassretain]:割り当て解除されたインスタンス0x6e78580に送信されたメッセージで、場合によってはブランチの[userDefaultssetObject行のブレークラインとしてXCodeが表示されます。

Switchをコンパイルするときにコンパイルを見たところ、クラスが作成されます。しかし、Java、C#、またはObj-Cのどの言語であるかはわかりません。クラスを終了し、スイッチクラスを実行しているため、userDefaults変数の割り当てが解除されます。これが、userDefaultsオブジェクトの割り当てが解除される理由です。今、私はこのスイッチをどのように書いて動作させるかわからず、プロのように見えます。いずれの場合もuserDefaults変数を作成して、そこでフラッシュしたくありません。唯一の解決策は、このスイッチをif-elseに書き込むことです。

これは機能しています:

NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
    
    switch (selectedRow) {
            
        case 0://English
        {
            [userDefaults setObject:@"English" forKey:@"language"];
        }
            break;
        case 1:// Deutsch 
        {
            [userDefaults setObject:@"German" forKey:@"language"];   
        }
            break;
        case 2://Français
        {
            [userDefaults setObject:@"French" forKey:@"language"];         
        }
            break;
        case 3://Italiano
        {
            [userDefaults setObject:@"Italian" forKey:@"language"];       
        }
            break;
        case 4://Español
        {
            [userDefaults setObject:@"Spanish" forKey:@"language"];
        }
            break;
            
        default:
            break;
    }
    // flush:
    [userDefaults synchronize];

なぜ?

  • なぜそれが機能したのかわかりませんが、それよりも再びクラッシュしました。コード内で変数を移動しました:

    スイッチ(selectedRow){

          case 0://English
          {
              NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
              [userDefaults setObject:@"English" forKey:@"language"];
              // flush:
              [userDefaults synchronize];
          }
              break;
          case 1:// Deutsch 
          {
              NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
              [userDefaults setObject:@"German" forKey:@"language"]; 
              // flush:
              [userDefaults synchronize];  
          }
              break;
          case 2://Français
          {
              NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
              [userDefaults setObject:@"French" forKey:@"language"]; 
              // flush:
              [userDefaults synchronize];        
          }
              break;
          case 3://Italiano
          {
              NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
              [userDefaults setObject:@"Italian" forKey:@"language"];   
              // flush:
              [userDefaults synchronize];    
          }
              break;
          case 4://Español
          {
              NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
              [userDefaults setObject:@"Spanish" forKey:@"language"];
              // flush:
              [userDefaults synchronize];
          }
              break;
    
          default:
              break;
      }
    

これは再びクラッシュし、私は答えを確認するためにここに来ました

私は以下の提案を見ました:

NSArray * languages = [NSArray arrayWithObjects: @"English", @"German", @"French",@"Italian", @"Spanish", nil];
    NSString * selectedLanguage = [languages objectAtIndex: selectedRow];
    [[NSUserDefaults standardUserDefaults] setObject: selectedLanguage forKey:@"language"];

同じ行でこのクラッシュ:

[[NSUserDefaults standardUserDefaults] setObject: selectedLanguage forKey:@"language"];
  • なにが問題ですか?信じられない。***-[MyClass保持]:割り当て解除されたインスタンス0x6b532c0に送信されたメッセージ

MyClassはUIViewContollerです。言語を選択し、いくつかのボタンを押して1または2画面に移動すると、戻って言語を再度選択するとクラッシュしますが、常にそうとは限りません。しかし、クラッシュすると、常に同じ行に、常に同じエラーメッセージが表示されます。

何がありますか

userDefaults setObject 

ナビゲーション付き?

#------------------------------------------------- -本当の問題を手に入れました:解決策を見つけるのは簡単ではありません#------------------------------------ ---------------

私は次のように書きました:userDefaults setObjectまた私は書きました:これはARCプロジェクトであり、MyClassの保持で失敗します。これは私のコードではありません。

コードは、アクションシートを使用した言語選択です。検索を行うと、次のリンクが表示されます: ブロックを呼び出すEXC_BAD_ACCESS

  • そこから、保持するのではなく、どこかにコピーを生成する必要があることがわかります。問題は、なぜsetObjectで保持が必要なのかということです。さて、変更リスナーが追加されたので...

// [[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@ "language" options:NSKeyValueObservingOptionNew context:NULL];

コードが削除され、コールバックの内容がスイッチコードの後に​​移動され、問題が解決されました-コールバックを実行するために保持する必要はありません

4

3 に答える 3

2

この問題はObjective-Cに固有のものではなく、一般的にC /C++に固有のものです。この回答をご覧になることをお勧めします。

最初のコードの問題は、Objective-CコンパイラがNSStringsのインスタンス化に関連する魔法を実行することです。これにより、上記のリンク先の質問で説明されている問題が発生する可能性があります。caseつまり、ローカル変数をインスタンス化し、@"something"まさにそれを実行しているすべてのステートメントを中かっこで囲む必要があります。

于 2012-04-27T13:02:38.447 に答える
1

あなたの質問への答えではありませんが、を捨ててswitch使用するのはどうですか?

NSArray * languages = [NSArray arrayWithObjects: @"English", @"German", @"French",
                                                 @"Italian", @"Spanish", nil];
NSString * selectedLanguage = [languages objectAtIndex: selectedRow];
[[NSUserDefaults standardUserDefaults] setObject: selectedLanguage forKey:@"language"];
于 2012-04-27T12:43:11.650 に答える
1

部分的な答え:

Objective-Cのswitch-caseステートメントでは、ケースでivarを宣言する場合は、2番目の例で行ったように、ケースを中かっこで囲む必要があります(ただし、私が見た例では、breakステートメントを中かっこで囲んでいます)。

あなたのcaseステートメントは変数を宣言していませんが、おそらくNSUserDefaultsが効果的にオブジェクトを作成しており、中括弧が必須になっています。(編集:starbugsが以下の彼の答えに記しているように、@ "Language"と書くと、オブジェクトをインスタンス化しています。)

では、2番目の例が機能する場合は、それを使用してみませんか?それはどのように専門家ではないように見えますか?特に、ケーススイッチ用の追加のブレースがObjective-Cの標準であることを考慮すると。

于 2012-04-27T12:37:35.950 に答える