В широком смысле convenience метод - это вспомогательный метод созданный для того чтобы более сложная задача решалась более легко. Само название convenience означает удобство. Т.е. это метод созданный для того чтобы было удобно решать с его помощью более сложные задачи.
В примере ниже метод createWithString является convenience методом для создания экземпляров класса MyClass (в данном примере по сути это еще и фабричный метод).
В примере ниже метод createWithString является convenience методом для создания экземпляров класса MyClass (в данном примере по сути это еще и фабричный метод).
// // MyClass.h // #import <Foundation/Foundation.h> @interface MyClass : NSObject @property (strong) NSString *myString; - (id)init; - (id)initWithString:(NSString *)aString; + (NSString *)transformString:(NSString *)aString; + (id)createWithString:(NSString *)aString; @end
// // MyClass.m // #import "MyClass.h" @implementation MyClass - (id)init { self = [super init]; if (self) { // Do nothing } return self; } - (id)initWithString:(NSString *)aString { self = [super init]; if (self) { _myString = aString; } return self; } + (NSString *)transformString:(NSString *)aString { return [aString uppercaseString]; } + (id)createWithString:(NSString *)aString { #if !__has_feature(objc_arc) return [[[self alloc] initWithString:[self transformString:aString]] autorelease]; #else return [[self alloc] initWithString:[self transformString:aString]]; #endif } @end
Обратите внимание что self в статических методах указывает на класс, потому что в Objective-C всё является объектами, даже сами классы. Конечно здесь в статических методах вместо self можно было использовать имя класса MyClass, но это не дальновидно по той причине что наследники класса будут работать с классом своего предка, в то время как должны работать со своим собственным классом.
// // MySubclass.h // #import "MyClass.h" @interface MySubclass : MyClass @end
// // MySubclass.m // #import "MySubclass.h" @implementation MySubclass + (NSString *)transformString:(NSString *)aString { return [aString lowercaseString]; } @end
MySubclass является наследником MyClass. Соответственно он наследует метод createWithString. Если бы мы в методе createWithString вместо self мы написали бы MyClass, то вызов этого метода у MySubclass возвращал бы объект типа MyClass.
То же касается и метода transformString, он вызывается у объекта self. Соответственно MyClass вызовет свою реализацию этого метода, а его наследник MySubclass свою (если она имеется).
То же касается и метода transformString, он вызывается у объекта self. Соответственно MyClass вызовет свою реализацию этого метода, а его наследник MySubclass свою (если она имеется).
// // main.m // #import <Foundation/Foundation.h> #import "MyClass.h" #import "MySubclass.h" int main(int argc, const char * argv[]) { @autoreleasepool { MyClass *theMyObject1 = [MyClass createWithString:@"Hello, World!"]; NSLog(@"%@", [theMyObject1 myString]); MySubclass *theMyObject2 = [MySubclass createWithString:@"Hello, World!"]; NSLog(@"%@", [theMyObject2 myString]); } return 0; }
Вывод программы:
2014-12-17 18:08:07.859 MyExample[3358:303] HELLO, WORLD!
2014-12-17 18:08:07.861 MyExample[3358:303] hello, world!
Program ended with exit code: 0
--