0

プログラムで pickerView を作成し、pickerView:numberOfRowsInComponent のような独自のバージョンのメソッドを使用させたいと考えています。

実行時に次のようにインスタンスを作成します。

UIPickerView *myPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 200, 320, 200)];
myPickerView.delegate = self;
myPickerView.dataSource = self;
myPickerView.showsSelectionIndicator = YES;
[self.view addSubview:myPickerView];

呼び出される標準的なメソッドは次のとおりです。

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    NSUInteger numRows = 5;
    return numRows;
}    

私がやりたいのは、この標準メソッドをこのインスタンス専用の別のメソッドに置き換えることです。

-(NSInteger)xxxpickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{ // special method for this instance only
    return 1;
}

メソッド swizzle を使用して他のことでこれを行うことができましたが、UIPickerView で動作させることができないようです。

@implementation UIPickerView (Tracking)
+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        SEL originalSelector =   @selector(pickerView:numberOfRowsInComponent:);
        SEL swizzledSelector = @selector(xxxpickerView:numberOfRowsInComponent:);

      Method originalMethod = class_getInstanceMethod(class, originalSelector);
      Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
      BOOL didAddMethod =
      class_addMethod(class,
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));

      if (didAddMethod) {
          class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
      } else {
          method_exchangeImplementations(originalMethod, swizzledMethod);
      }

  });

}

実行時に 2 番目のメソッドがインスタンスに追加され、それがリストに含まれているかどうかを確認するために、メソッドをリストしました。

ただし、2 番目の方法は実行されず、1 番目の方法は実行されます。

これを始めた投稿へのリンクは次のとおりです。動作することを確認しましたが、これについて何かが欠けているようです。 http://nshipster.com/method-swizzling/

私が解決しようとしている問題は、同時に実行される別のインスタンスに依存しない UIPickerView オブジェクトのインスタンスを作成したいということです。したがって、1 つのインスタンスでのみ機能し、実行中の可能性のある他のインスタンスを完全に無視する別の方法が必要であり、これをプログラムで実行したいと考えています。

タグ/スイッチを使用しない理由の少なくとも 1 つは、実行時まで条件がどうなるかわからないことです。

スウィズルがあるオブジェクトで機能し、別のオブジェクトで機能しない理由がわかりません。また、実行時にストック メソッドを他のオブジェクトに置き換える他の方法を受け入れることもできます。

私が置き換えようとしている方法について、それを置き換えることができない何かがありますか?

編集:質問を明確にするために、リンク内の次のコードが機能します。あるメソッドを別のメソッドに交換します。私がする必要があるのは、別のオブジェクトに対して同じことであり、あるオブジェクトでは機能するが別のオブジェクトでは機能しないことを理解できません。

これは別のオブジェクトでも機能します: http://nshipster.com/method-swizzling/

ここにも別のリンクがあります: http://blog.newrelic.com/2014/04/16/right-way-to-swizzle/

4

1 に答える 1

0

これを行う簡単な方法の 1 つは、ポインターのコピーをプロパティに保持し、データソース/デリゲート メソッドでポインターを比較することです。

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    if ( pickerView == self.myPickerView )
        return 1;   // response for this particular picker view
    else
        return 5;   // standard response
}
于 2015-03-01T09:30:26.167 に答える