1.2 类方法的self

引用上一篇文章,下面通过alloc 和initWithName的方式来创建Person对象

- (instancetype)initWithName:(NSString *)name {
    if (self = [super init]) {
        _name = name;
        _headImg = [UIImage imageNamed:@"default_head"]
    }
    retrun self;
}

虽然禁用了init方法,但是通过super调用父类的init并不会影响。如果经常使用这个方法用类来创建

+(instancetype)initWithName:(NSString *)name

既然有了类方法,实例方法就不需要了

#import <Foundation/Foundation.h>
@class UIImage

NS_ASSUME_NONNULL_BEGIN

@interface Persion : NSObject

@property (nonatomic, strong, nullable) UIImageView *headImg;
@property (nonatomic, copy, nonnull) NSString *name;

- (instancetype)initWithName:(NSString *)name NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)new NS_UNAVAILABLE;

+ (instancetype)personWithName:(NSString *)name;

@end

NS_ASSUME_NONNULL_END

因为之前- (instancetype)initWithName: 的实现,我们希望加入新的
错误代码

+ (instancetype)personWithName:(NSString *)name {
    Person *p = [[ Persion alloc]initWithName:name];
    return p
}

原因,解决办法

+ (instancetype)personWithName:(NSString *)name {
    Person *p = [[self alloc]initWithName:name];
    return p
}

将Persion 换成self
self 表示当前类,而不一定是Person类

在举一个例子
Animal 类init 不可用

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Animal : NSObject

@property (nonatomic, copy) NSString *name;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)animalWithName:(NSString *)name;
@end

NS_ASSUME_NONNULL_END


- (instancetype)animalWithName:(NSString *)name {
    Animal *animal = [[self alloc]init];
    animal.name = name;
    return animal;
}

此时如果换成animalWithName: 方法里面 [[self alloc]init]; 换成
[[Animal alloc]init]; 会报错,错误很明显,
在创建一个类Dog继承与Animal

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface Dog : Animal

@end

NS_ASSUME_NONNULL_END

此时用下面代码依然会报错原因init方法父类禁用了

Dog *dog = [[Dog alloc]init];

假设在animalWithName: 方法中用的是[[Animal
alloc]init],那么用它来创建Dog实例肯定是不对的,因为当前类是Dog。

如果用self 来创建的话则没有此问题,因为对于Dog来说self 指的是Dog,self
代表具体当前的那一个类,=因此返回结果是Dog实例

思考加入我们就是Animal类init不可用,但是Dog类可以使用???

可以在Dog 头文件再声明一次

@interface Dog : Animal

- (instancetype)ini;

@end

但是编译器会告诉我们ini没有实现的警告!我们知道NSObject 类默认实现的,此处报警告从主观的意识上有一些不合理,但毕竟是负责的编译器,为了防止这样的警告可以手动去除警告。

#pragma clang diagnostic ignored "-Wincomplete-implementation"

总结

  1. 类方法中的self 指的是当前类,而不是国定的某一个类还可以是这个类的子类;
  2. 对于父类禁用的方法,需要在子类头文件中再次声明才可以使用,并需要在类实现消除编译警告。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值