本文为大地瓜原创,欢迎知识共享,转载请注明出处。
虽然你不注明出处我也没什么精力和你计较。
作者微信号:christgreenlaw
如果只有方法的实现而没有声明,那么类外部无法直接调用此方法。该方法就成为了表面上的私有方法。但是,OC中没有真正的私有方法,因为OC采用的是消息机制。
{}形式的实例变量(成员变量)可以在@interface
中定义,也可以在@implementation
中定义。而在@implementation
中定义的变量和用@private
修饰的变量又不太一样,在@implementation
中定义的变量只能在本类中访问,其它类无法查看。
@property
是一个编译器指令。
@synthesize
是一个编译器指令, 它可以简化我们getter/setter方法的实现。
在@synthesize后面告诉编译器,将要使用的property叫什么,对应的实例变量叫什么。例子如下:
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}
//@synthesize age = _age;
- (void)setAge:(int)age
{
_number = age;
}
- (int)age
{
return _number;
}
//@synthesize age = _number;
如果在@synthesize后面没有告诉系统将传入的值赋值给谁, 系统默认会赋值给和@synthesize后面写得名称相同的成员变量(Xcode4.4之前这个才有意义,目前的@property实现默认就是这样)
@synthesize age;
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}
在目前的实现中,当@property声明了一个变量,默认就会使用对应的下划线开头的实例变量(这个实例变量就不必用花括号的形式写出了)。但需要注意的是:它只会生成最简单的getter/setter,不会对其进行其他操作。若需要对数据进行处理,则需要我们自己重写getter/setter。
注意!!!!如果你同时重写了getter和setter,那么@property将不会为你生成下划线开头的实例变量!!!你需要手动在花括号中声明实例变量!!!
property修饰符
@property(readwrite) int age;
@property(getter=myName) NSString* name;
@property(setter=giveName:) NSString* name;
@property(getter=myName,setter=giveName:) NSString* name;
@property(readonly) NSString* id;
@property(getter=isMarried) NSString* married;
//能用修饰符处理的getter/setter就尽量不要额外去写了,统一用修饰符处理
id
id是一个动态数据类型,可以用来:
- 定义变量
- 作为函数参数类型
- 作为函数返回值类型
一般情况下,所有的数据类型都是静态数据类型,也就是说:
- 编译时就知道是什么类型
- 知道类型有哪些方法和属性
- 编译时就可以确定的访问类型的方法和属性
- 若通过静态类型定义变量,那么访问不属于静态类型的方法或属性,编译器会报错,无法通过编译
作为动态类型:
- 编译时不知道真是的类型,运行时才知道它的真实类型
- 通过动态数据类型定义变量,如果访问不属于动态数据类型的方法或属性,编译时不会报错
一句话总结:动态数据类型,编译器不知道你的真实类型,静态类型反之
- 通过静态数据类型定义变量, 不能调用子类特有的方法
- 通过动态数据类型定义变量, 可以调用子类特有的方法
- 通过动态数据类型定义的变量, 可以调用私有方法
为了避免动态数据类型调用不属于自己的方法而引发的运行时错误,一般在使用前进行判断,是不是能够调用某方法:
if ([obj isKindOfClass:[Student class]]) {
// isKindOfClass , 判断指定的对象是否是某一个类, 或者是某一个类的子类
[obj eat];
}
if ([obj isMemberOfClass:[Student class]]) {
// isMemberOfClass : 判断指定的对象是否是当前指定的类的实例
[obj eat];
}
new方法其实就是alloc + init
默认情况下init(NSObject)什么都没有做
alloc则初始化了isa实例变量,使其指向了自己所在的类,其他所有实例变量的值都设为0
由于历史原因,alloc会触发allocWithZone:
以上引用内容来自苹果文档。