1

iOS6用のUIRefreshControlを追加しようとしています。

#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
    UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
    refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to Refresh"];
    [refresh addTarget:self action:@selector(refreshView:)
      forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refresh;
}

if (NSClassFromString(@"UIRefreshControl") != Nil) {
    UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
    refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to Refresh"];
    [refresh addTarget:self action:@selector(refreshView:)
      forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refresh;
}

しかし、エラーが発生します

dyld: Symbol not found: _OBJC_CLASS_$_UIRefreshControl
Referenced from: /Users/office/Library/Application Support/iPhone    Simulator/4.3.2/Applications/DD532E42-77F9-471C-AA48-7F9EAE9268C6/Verizon.app/Verizon
Expected in:   /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/i PhoneSimulator4.3.sdk/System/Library/Frameworks/UIKit.framework/UIKit

私はIOS6SDKを使用しており、iPhone4.3Simulatorで実行しています。

コードを削除すると

    UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
    refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to Refresh"];
    [refresh addTarget:self action:@selector(refreshView:)
      forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refresh;

すべてがiPhone4.3シミュレータで動作します。興味深いことに、内部のコード

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {  }

iPhone 4.3シミュレーターでは、エラーが発生する理由がわからないため、呼び出されることはありません。助けてください!!

4

2 に答える 2

1

コードが呼び出されないことを忘れないでください。アプリケーションが読み込まれると、ダイナミックリンカーはアプリのバイナリがリンクされているダイナミックライブラリ内のすべてのシンボルを解決する必要があります。iOS 4.3では、UIRefreshControlクラスは実装されていないため、このOS(およびiOS 6より前のOS)を実行しているデバイスでは、オペレーティングシステム自体(まあ、UIKitフレームワーク)にはクラスとそれに対応するシンボルが含まれていません。そのため、iOS6のみに適したコードを使用していなくても、アプリケーションを起動することさえできません。

また、プリプロセッサマクロはコンパイル時に評価されることを知っておく必要があります。ターゲットがiOS 6の場合、条件付きでコンパイルするコードがコンパイルされ、プログラムを実行しているiOSのバージョンに関係なく、システムはそれを実行しようとします。の上。

解決策:条件付きコンパイルを使用する代わりに、リフレクションと自己イントロスペクションを使用して、実行時にクラスが使用可能かどうかを確認します。

Class UIRefreshControl_Class;
if ((UIRefreshControl_Class = objc_getClass("UIRefreshControl")) != Nil) {
    // class available
    id control = [[UIRefreshControl_class alloc] init];
    // etc.
}
于 2012-10-16T17:22:04.663 に答える
1

間違いなく2番目のスタイル、すなわち:

if (NSClassFromString(@"UIRefreshControl") != nil) {
    ...
}

発生しているエラーについては、プロジェクトの「ビルドフェーズ」設定の「リンクバイナリとライブラリ」セクションでUIKitを「オプション」に設定することで、エラーを防ぐことができます。

iOS 6でのみ利用可能なクラスを使用していることに気付くので、オプションとしてマークする必要がありますが、何らかの理由でそうではないように見えます。

于 2012-10-16T17:24:31.270 に答える