3

私はiPadとiPhoneの両方でネイティブに実行されるユニバーサルアプリを書いています。また、古いデバイス(4.0を実行できないデバイス)をターゲットにする必要があるため、3.1は必須です。

Base SDKを利用可能な最新バージョン(4.2)に設定し、DeploymentTargetを3.1に設定しました。適切なデバイス/バージョンでのみ対応するメソッドを呼び出すために、多くのランタイムチェックを行っています。

私がiPadで利用しているものの1つは、UISplitViewControllerです。splitViewControllerデリゲートを割り当てると、クラスインターフェイスがUISplitViewControllerDelegateプロトコルを明示的に採用していないため、コンパイラは警告をスローします。そうするように宣言すると、UISplitViewControllerがない古いデバイスでアプリがクラッシュするのではないかと心配しています。 /UISplitViewControllerDelegate。

コンパイラの警告を抑制する最良の方法は何ですか?「空の」UISplitViewControllerDelegateを宣言する必要がありますか?もしそうなら、私は実行時に条件付きでそれを作ることができますか?または、対応するクラスインターフェイスをプロトコルに準拠させ、古いデバイスについて心配する必要はありませんか?

一番、

4

3 に答える 3

1

私はこれを試していませんが、プロトコルを持たない古いランタイムでクラスが使用されている場合でも、無条件にプロトコルを採用できると確信しています。その理由は次のとおりです。

プロトコルを定義するためのすべての情報は、.h ファイルを宣言する .h ファイルに含まれています@protocol。プロトコルを採用すると、そのプロトコル宣言は .h ファイルのある時点で (おそらく によって#import <UIKit/UIKit.h>) インポートされます。

ランタイムがプロトコルについて何かを知る必要がある場合、ランタイムは「プロトコル オブジェクト」を参照します。これは通常、ソース コードで を実行して参照します@protocol(MyProtocolName)The Objective-C Programming Language documentationのProtocol Objectsというタイトルのセクションに従って、そのようなプロトコル参照が検出されると、コンパイラはこのプロトコル オブジェクトを (コンパイル時に) 作成します。

したがって、プロトコルを採用し、プロトコル オブジェクトを参照するコードを記述した場合、そのプロトコル オブジェクトはコンパイラによって作成されます。古いデバイスで実行している場合でも、コンパイラによってそのプロトコル オブジェクトが作成されているはずなので、クラッシュすることはないと思います。

それが理にかなっていることを願っています。3.1 から 4.2 までの範囲の iOS バージョンを実行しているデバイスを使用しているため、時間があれば、これを試して実際に有効かどうかを確認できます。

于 2010-11-05T16:20:31.750 に答える
1

You can suppress the warning with a simple C cast:

foo.delegate = (id<UISplitViewControllerDelegate>)self;
于 2010-11-03T04:43:09.533 に答える
0

印刷を使用し、アプリを 4.2 より前に実行したい場合も同じ問題が発生します。基本的にはこれで動作します

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40200
// code for iOS 4.2++
@interface PersonDetailViewController : UITableViewController <EditViewControllerDelegate, EditPickerViewControllerDelegate, UITextFieldDelegate, UIActionSheetDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIPrintInteractionControllerDelegate>{
#else
// code for iOS til 4.1
@interface PersonDetailViewController : UITableViewController <EditViewControllerDelegate, EditPickerViewControllerDelegate, UITextFieldDelegate, UIActionSheetDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>{
#endif

しかし... InterfaceBuilder はこれを処理できないようです。すべてのアウトレットは、IB でこの条件付き定義がなくなった後に定義します。

それで、より良い解決策はありますか?

よろしくゲルト

于 2010-11-05T16:00:30.707 に答える