3

私はここで何をしましたか?メソッドのパラメーターは型なしにできますか?

正常に動作する最近のプロジェクトでは、アプリは既にストアにあります-これまでのところ問題はありません.hファイルで次のことを行いました:

@property (strong, nonatomic) NSManagedObject          *myPerson;
- (HKPersonPicker*) initWithPerson:person;
- (HKPersonPicker*) initWithPerson:person delegate:(id <HKPersonPickerDelegate>)delegate;

私はこのようにするつもりでしたが、しませんでした:

- (HKPersonPicker*) initWithPerson:(NSManagedObject*)person;
- (HKPersonPicker*) initWithPerson:(NSManagedObject*)person delegate:(id <HKPersonPickerDelegate>)delegate;

.m ファイルの対応する部分:

- (HKPersonPicker*) initWithPerson:person
{
    self = [super init];
    if(self){
        self.myPerson = person;
    }
    return (self);
}

- (HKPersonPicker*) initWithPerson:person delegate:(id <HKPersonPickerDelegate>)delegate
{
    self = [self initWithPerson:person];
    if(self){
        self.delegate = delegate;
    }
    return (self);
}

ご覧のとおり、この person オブジェクトに対して特別なことは何もしていません。プロパティ myPerson に割り当てただけです。オブジェクトのメソッドを呼び出したり、そのデータにアクセスしたりしなかったので、コンパイラはそのオブジェクトについて何も知る必要がありませんでした。しかし、コンパイラの視点からはどうなるのでしょうか? タイプID? ただ何か?デフォルトのタイプはありますか?

ご覧のとおり、私には実際の問題はありません。ただ興味があるだけ。この質問が SO ルールに違反しないことを願っています。

4

3 に答える 3

3

C ではデフォルトの型は ですintが、Objective-C ではidです。

于 2013-03-06T20:41:27.427 に答える
2

メソッドの型宣言の欠落は、デフォルトでid. IIRC では、Apple のランタイム ライブラリで戻り値の型を持たないメソッドがかなりの数見られます。

于 2013-03-06T20:42:01.647 に答える
2

あなたがしていることに決定的な問題はありませんが、同時にコーシャでもありません. 明確にするため、および一貫性のある優れた Cocoa のようなコード スタイルを維持するために、型宣言を行う必要があります。

したがって、実際には次のようになります。

- (GSPersonPicker*) initWithPerson:(id)person;

そして、プロパティ宣言を実際に変更する必要があります。

@property (strong, nonatomic) id *myPerson;

それが変更されていない場合、コードは混乱します。入ってくるタイプを知っています。したがって、タイプを使用して、意味のある警告/エラーをコンパイラに提供させてください。また、おそらくタイプ「HKPerson」またはエンティティに名前を付けたものを使用する必要があるため、コンパイラは「HKPlace」を渡しても問題ないと判断します(タイプは「id」と「NSManagedObject」の両方になります) '、それはあなたに何の恩恵もありません)

さらに重要なことは、理由がない限り動的タイプ (id) を使用しないことです。コンパイラはあなたを助けるためにそこにあります。エラーや警告はあなたの友人です。それらはコンピューターではなく、あなたが台無しにしたことを教えてくれます。「id」を使用すると、コンパイラーは、ああ、ここには何でも入ることができます!!! また、そのメソッドにすべてを破壊するタイプを送信した場合、エラーは検出されません。

ここで、ポリモーフィズムを使用するとします。IE、私たちの人を定義する、複数のクラスが準拠するための一般的なプロトコルを宣言しましょう。

@protocol GSPerson
-(NSUInteger)age;
@end

それでは、いくつかのクラスを定義し、それらをプロトコルにサブスクライブさせます (ニンジンマークダウンの間にある GSPersonは私を殺しています笑):

#import "GSPerson.h"
@interface GSSpecialPerson <GSPerson>
// code
@end

#import "GSPerson.h"
@interface GSWeirdPerson <GSPerson>
// code
@end

次に、プロトコルに準拠するようにメソッド シグネチャを再定義します。

- (GSPersonPicker*) initWithPerson:(id<GSPerson>)person;

そして、私たちのプロパティ宣言:

@property (strong, nonatomic) id <GSPerson> *myPerson;

これで、コンパイラは、そのメソッドに渡すものはすべて、上で定義した GSPerson プロトコルに準拠する必要があることを認識します (つまり、人の年齢を返すメソッドが必要です)。他のものを渡そうとすると、コンパイラの警告がスローされますが、これは良いことです。

さらに良いことに、必要なメソッドが欠落している場合、ポリモーフィック クラスに警告がスローされます。

于 2013-03-06T20:54:50.290 に答える