巧妍度假旅馆

【兼程并进】iOS便捷方法

来源:ok-bmob    发布时间:2019-06-17 17:56:04
在Objective-C中,如果某个类方法的返回类型是这个类的对象(例如stringWithFormat:和randomPossession),就可以将这种类方法称为便捷方法(conveniencemethod)。

在便捷方法中,应该使用self,而不是直接使用类的类名。这样,子类也能使用父类的便捷方法,不至于发生错误。

例如,现在有一个Person类和一个Student,Student类是Person的子类。
实现代码如下:

Person.h
#import <Foundation/Foundation.h>

@interface Person : NSObject

@property (nonatomic,readwrite,copy) NSString* name;
//指定初始化方法
-(instancetype)initWithName:(NSString*)name;
//便捷方法
+(instancetype)getPersonWithName:(NSString*)name;
@end
Person.m
#import "Person.h"

@implementation Person

-(instancetype)initWithName:(NSString*)name{
   self = [super init];
   if (self) {
       _name = name;
   }
   return self;
}

-(instancetype)init{
   return [self initWithName:@"name"];
}

+(instancetype)getPersonWithName:(NSString*)name{
   return [[Person alloc] init];
}

@end
main.m
#import <Foundation/Foundation.h>
#import "Student.h"

int main(int argc, const char * argv[]) {
   @autoreleasepool {
       Student *student = [Student getPersonWithName:@"xiaoming"];
       NSLog(@"%@",student.schoolName);
   }
   return 0;
}
特别要注意,Person.m中的下面代码
+(instancetype)getPersonWithName:(NSString*)name{
   return [[Person alloc] init];
}
这里直接使用类名来进行初始化,那么调用该方法时返回的对象是Person对象,在main.m中子类Student调用了该方法,并且试图去读取子类特有的成员变量,如例子中的schoolName时就会报错。报错内容如下:
-[Person schoolName]: unrecognized selector sent to instance 0x100206c90
也就是说实际上调用 +(instancetype)getPersonWithName:(NSString*)name 后返回的是Person对象,而Person对象并没有schoolName这个成员变量。因此报错。

那我们怎么解决该问题呢?实际上很简单,我们将类名,即Person用self来替换就可以了。代码如下:
+(instancetype)getPersonWithName:(NSString*)name{
   return [[self alloc] init];
}
在类方法里面使用self代表的是调用该方法的类自身。我们可以打个断点看一下。如下图:
也就是说我们在便捷方法中返回的对象要用self来发送消息,而不是用类名,这样子类也可以很方便地使用父类的便捷方法。



编辑:纪是