2015-03-01 5 views
0

Я хочу создать pickerView программно и использовать его собственную версию метода, например pickerView: numberOfRowsInComponent.Как заменить pickerView: метод numberOfRowsInComponent для 1 экземпляра pickerView

Я создаю экземпляр во время выполнения, как это:

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); 
     } 

    }); 

}

Я перечислил методы, чтобы увидеть, если второй метод был добавлен к примеру во время выполнения, и это находится в списке.

Однако второй способ не запускается, первый метод выполняется.

Вот ссылка на сообщение, которое заставило меня начать с этого, и я подтвердил, что он работает, но мне кажется, что что-то не хватает об этом. http://nshipster.com/method-swizzling/

Я открыт для других предложений, проблема, которую я пытаюсь решить, что я хочу, чтобы создать экземпляр объекта UIPickerView, который не будет зависеть от другого экземпляра, который будет запущен в том же время. Поэтому мне нужен другой метод, который будет работать только с одним экземпляром и полностью игнорировать любые другие экземпляры, которые могут быть запущены, и я хочу сделать это программно.

По крайней мере, одна из причин не использовать тег/переключатель - это то, что я не знаю, какими будут условия до выполнения.

Я не знаю, почему swizzle будет работать с одним объектом, а не с другим, и я открыт для другого способа замены методов запаса другими во время выполнения.

Есть ли что-то о методе, который я пытаюсь заменить, который не позволит его заменить?

EDIT: для того, чтобы попытаться устранить неполадку, работает следующий код в ссылке. Он меняет один метод для другого метода. То, что мне нужно сделать, это одно и то же для другого объекта, и я не могу понять, что он работает для одного объекта, а не другого.

Это работает для другого объекта: http://nshipster.com/method-swizzling/

Вот еще одно звено, а также: http://blog.newrelic.com/2014/04/16/right-way-to-swizzle/

ответ

0

Один простой способ сделать это сохранить копию указателя в свойстве, а затем сравнить указатели на источник данных/делегата.

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 
{ 
    if (pickerView == self.myPickerView) 
     return 1; // response for this particular picker view 
    else 
     return 5; // standard response 
} 
+1

Возможно, используя тег или какой-либо другой уникальный способ распознавания сборщика, поскольку шипение кажется слишком большим количеством хлопот в этом случае ... –

+0

Я использовал это раньше, и вы правы, он будет выполнять эту работу в большинстве случаев, но мне нужно, чтобы pickerView запускал другой метод, отличный от стандартного. Подход swizzle заменит один метод для другого метода, как показано в ссылке выше, мне просто нужно выяснить, почему это работает для одного объекта, а не другого. Он отлично работает для UIView, но не UIPickerView. Мне интересно, должен ли я подкласс UIPickerView 1st. – KarlJay

+0

Может, я поеду не так. Это то, что я хочу сделать: создать несколько экземпляров класса (например, UIPickerView), чтобы каждый экземпляр класса имел свои собственные методы. Поскольку это работает сейчас, они обмениваются методами, я хочу, чтобы у них были свои уникальные методы. Они будут созданы во время выполнения и код, используемый каждым методом, будет определен во время выполнения. – KarlJay

Смежные вопросы