2013-10-01 3 views
2

У меня есть класс с функцией, которую нужно вызывать изнутри и снаружи класса. Следующий код работает отлично, но мне было интересно, есть ли способ иметь только один метод lowerKeyboard вместо двух методов с - и +? Если я буду держать только метод + я получаю сообщение об ошибке unrecognized selector sent to instance при попытке вызова метода из внутри классатакой же метод, например, и метод класса. Возможное?

Изнутри класса:

-(void)someOtherMethod 
{ 
    UIBarButtonItem *infoButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(lowerKeyboard)]; 
} 

вне класса:

[myClass lowerKeyboard]; 

MyClass:

-(void)lowerKeyboard 
{ 
    //do something 

} 

+(void)lowerKeyboard 
{ 
     //do the exact same thing 
} 
+0

Возможный дубликат [В чем разница между методами класса и экземпляра?] (Http://stackoverflow.com/questions/1053592/what-is-the-difference-between-class-and-instance-methods) –

+0

@DavidCaunt Ты выглядишь как тод от взлома! Я не просил разницы, я знаю разницу. Мой вопрос задает вопрос о том, как объединить эти два. – Segev

+0

Нет, он похож на меня! –

ответ

3

Допустим, вы имеете следующее:

- (void)doFoo 
{ 
    NSLog(@"Foo"); 
} 

+ (void)doFoo 
{ 
    NSLog(@"Foo"); 
} 

Вы можете реорганизовать это либо делать обе реализации так:

- (void)doFoo 
{ 
    [[self class] doFoo]; 
} 

+ (void)doFoo 
{ 
    NSLog(@"Do Foo!"); 
} 

Тем не менее, стоит отметить, что наличие двух названных подобным методам, как это прошу о проблеме. Вам было бы намного лучше удалить один из двух интерфейсов, чтобы избежать путаницы (особенно, поскольку вам нужна только одна копия реализации в любом случае!).

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

Технически, вы можете продублировать реализацию класса и реализацию экземпляра редактированием время выполнения примерно так:

// Set this to the desired class: 
Class theClass = nil; 
IMP classImplementation = class_getImplementation(class_getClassMethod(theClass, @selector(doFoo))); 
class_replaceMethod(theClass, @selector(doFoo), classImplementation, NULL) 

Это должно гарантировать, что вызов + [theClass doFoo] называет точно так же, как выполнение вызова - [theClass doFoo]. Он полностью удаляет исходную реализацию экземпляра из стека реализации класса (поэтому обрабатывайте с большой осторожностью). Я не могу думать о каких-либо действительно законных делах для этого, однако, так что относитесь к этому с щепоткой соли!

+0

Как настроить селектор на этот метод? Должен ли я просто установить его на другой метод, и этот метод должен вызвать [[self class] doFoo]; ? Если я установлю селектор на doFoo, я все равно получаю «непризнанный селектор, отправленный экземпляру» – Segev

+0

. Предложение @Sha David заключается в том, что у вас должен быть метод экземпляра, чтобы избежать этого «нераспознанного селектора».И мне нравится подход метода экземпляра, вызывающий метод класса намного лучше, чем первый подход (дублирование кода) или, yikes, замещение времени выполнения метода. – Rob

+1

@DavidDoyle +1, но, без обид, я вроде бы хотел, чтобы вы перестали даже предлагать подход 'class_replaceMethod'. Академически интересно, что вы можете это сделать, но, вау, я согласен, какая действительно плохая идея! lol – Rob

0
-(void)lowerKeyboard 
{ 
    //this can be called on class instance 

    //UIBarButtonItem *infoButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(lowerKeyboard)]; 
    //[infoButtonItem lowerKeyboard]; 
} 

+(void)lowerKeyboard 
{ 
    //this can be used as class static method 
    //you cannot use any class properties here or "self" 

    //[UIBarButtonItem lowerKeyboard]; 
} 
Смежные вопросы