1.1 创建并描述一个类

1.1 创建并描述一个类

开发经常需要创建类文件,可以说在项目开发过程中,很大一部分是由类组成的,要在Object-C创建一个类,需要继承NSObject或者子类,NSObject以及子类就是Object-C语言对象的实现。

打开NSObject 的定义,可以看到其头文件中仅有一百多行代码,及定义了对象及其本方法。

@interface NSObject <NSObject> {

 Class isa  OBJC_ISA_AVAILABILITY;

}

NSObject 其实是实现了同名协议的接口(Interface),参数只有一个isa ,指向当前所属的类,在NSObject的协议中,不通的NSObject的类,需要根据实际情况来重写部分方法。

在开发中,如何去继承一个NSObject 类呢?
下面一个简单的例子
简单的创建一个类继承与NSObject的对象后,文件结构目录上会多两个文件Person的

  • 头文件.h

头文件一般都是对这个类起到一个介绍的作用,开发者可以通过头文件来获取改类的一些基本信息,
包括类的属性和方法,从而不需要关心改类是如何实现的

  • 实现文件.m

实现文件的代码量会比头文件多一些,针对头文件提供的属性和方法,实现文件应该提供具体的实现,从而保证这个类被很好的使用。

打开Person.h文件内容如下

#import <Foundation/Foundation.h>

@interface Person : NSObject

@end

导入Foundation 框架。Foundation框架是系统的基于CoreFoundation 框架的封装,即常说的Cocoa 框架,包含数据集合,日期,文件的处理,KVO/KVC,Runloop以及网络通信等已系列基本功能类的集合。
在头文件导入的框架尽量不要重复,如果Person类有一个UIImage的属性headImage,则需要在头文件加入UIKit文件

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

此时加入UIKit框架后可以不需要加入#import <Foundation/Foundation.h>框架,因为UIKit框架默认包含了Foundation框架,重复的包含是无意的,并且使代码看起来并没有那么简洁了,还有Person是一个模型类,并不是展示类,导入UIKit框架,会给开发者造成困扰,通常来说第一个#import 的框架可以很明确的让开发者明白改类是属于哪一种类型,所以此时的做法应该为所需要的UIImage添加一个向前的声明

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

@interface Person : NSObject

@property (nonatomic, strong) UIImageView *headImage;

@end

接下来我们会想为*Person这个类添加字符串,name 属性,而且是必须的,而刚才提到的headImage,可能为nil,在这种情况下为了兼容Swift 的可选类型,会在property 中加上特性的修饰符:nonnull nullable

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

NS_ASSUME_NONNULL_BEGIN

@interface Person : NSObject

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

@end

NS_ASSUME_NONNULL_END

如果一个类的属性很多,这样做很麻烦,可以利用系统提供的NS_ASSUME_NONNULL_BEGIN/NS_ASSUME_NONNULL_END 默认属性设置为nonnull。
属性写完后,就需要初始化一个方法,需要在初始化的时候传递一个NSString 的name ,并且最好能给headImage 附上一个默认的头像。

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

NS_ASSUME_NONNULL_BEGIN

@interface Person : NSObject

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

- (instancetype)initWithName:(NSString *)name 

@end

NS_ASSUME_NONNULL_END
#import "Person.h"
#import <UIKit/UIImage.h>

@implementation Person

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

@end

看似很简单,似乎没有什么复杂的地方,可是当代码提交之后,协调的开发同事需要使用你的Persion 类创建实例时,却发现并没有默认的头像,这个时候你会感到疑惑,仔细一看同事的代码这样写:

 Person *tom = [[Person alloc]init];
 tom.name = @"Tom";

同事并没有使用你想让他使用的初始化方法,只使用了最基本的alloc和init, 这是协同开发中常遇到的问题,
如何让同事页使用自己提供的方法呢?

#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;

- (instancetype)init NS_UNAVAILABLE;
- (instancetype)new NS_UNAVAILABLE;

@end

NS_ASSUME_NONNULL_END

NS_UNAVAILABLE 修饰在头文件中禁用其他初始化方法,可保证只有自己提供的初始化的方法才是唯一的途径,此时要创建Person 实例,只能通过initWithName 的初始化方法

总结

  1. 创建类应尽量明确类型,必要时加上前向声明
  2. 属性当表明可选还是不可选
  3. 通过NS_UNAVAILABLE 禁用相关的方法。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值