//NSDate是Foundation框架中表示日期、时间、时区的一个类。
//获取当前时间
NSDate *date = [NSDate date];
NSLog(@"%@",date);
NSDate *date1 = [NSDate dateWithTimeInterval:10 sinceDate:date];
NSLog(@"%@",date1);
NSTimeInterval seconds = [date1 timeIntervalSince1970];
NSLog(@"%f",seconds);
//表示当前时间点 一天之后的时间点
NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow:24 * 60 * 60];
NSLog(@"%@",tomorrow);
//日期格式类 NSDateFormatter
//这个类的主要功能是实现 NSDate 与 NSString 的互转。
//日期格式有:
/**
* 1、y 年
2、M 月
3、d 日
4、H(24小时制)、h(12小时制am/pm) 小时
5、m 分钟
6、s 秒
*/
//1、将字符串 按照 给定的格式 转换成NSDate对象
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//设置date格式
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *str = @"2015-10-19 11:59:59";
//转换成NSDate对象
NSDate *someDate = [dateFormatter dateFromString:str];
NSLog(@"%@",someDate);
//2、将NSDate 按照 给定的格式 转换成NSString
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
//设置date格式
[dateFormatter1 setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *nowDate = [NSDate date];
NSString *dateStr = [dateFormatter1 stringFromDate:nowDate];
NSLog(@"%@",dateStr);
//通过KVC 实现 对 实例变量的赋值 和 取值
[person setValue:@"zhangsan" forKey:@"name"];
//此方法的作用是为了 防止通过setValue:forKey:赋值时,如果key对应的实例变量不是对象类型,而value给了nil产生崩溃。
//此方法如果不重写 会 抛出异常。
- (void)setNilValueForKey:(NSString *)key {
}
//此方法的作用 是防止 通过setValue:forKey:赋值时,key对应的实例变量并没有声明产生崩溃。
//如果此方法不重写,会 抛出异常。
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
}
//如果出现赋值,并且点语法在等号左边,就是setter。
//此时点语法相当于 setter方法
man.name = @"lisi";//man 的 name 为 某个字符串。
//此时的点语法相当于getter方法
NSLog(@"%@",man.name);
@interface Person : NSObject
{
NSString *_name;
NSInteger _age;
}
//属性是一对setter、getter方法,并不是变量,既然是方法就会有声明和实现
//声明属性采用@property关键字。
//属性的类型决定了 相对应的 setter方法中的参数类型 以及 getter方法中的返回值类型。
@property NSString *name;//声明一个字符串类型的属性name。
@property NSInteger age;
//属性就等价于下面的两行代码。
//- (void)setName:(NSString *)name;
//- (NSString *)name;
//- (void)setAge:(NSInteger)age;
//- (NSInteger)age;
- (void)sayHi;
@implementation Person
//属性的实现采用@synthesize关键字
//实现部分 的作用是 默认实现的setter方法 是为 等号 右边的实例变量赋值
//默认实现的getter方法 是取 等号右边实例变量的值
@synthesize name = _gender;
@synthesize age = _age;
//- (void)setName:(NSString *)name {
// _gender = name;
//}
//- (NSString *)name {
// return _gender;
//}
//
//- (void)setAge:(NSInteger)age {
// _age = age;
//}
//- (NSInteger)age {
// return _age;
//}
//同类型的属性可以放到同一行去声明,不同类型的绝对不允许放到同一行声明。
//属性是一对setter、getter方法,并且属性本身绑定了一个 实例变量,声明在类的延展里面,所以是私有的实例变量,外界不可以通过_name访问实例变量,所以增强了实例变量的访问安全性,如果外界想访问实例的话,只能通过方法。
//属性的属性第一类,读写性控制
/**
* 1、readonly,只读,属性只会生成getter方法,并没有setter方法
2、readwrite,可读可写,既有setter方法,又有getter方法。是读写性控制的默认属性,其中readonly与readwrite只能出现一种
3、setter,可以改变默认实现的setter方法的方法名,但是一般情况下不用
4、getter,可以改变默认实现的getter方法的方法名,通常用来修改BOOL类型的属性默认实现的getter方法名。
*/
//属性的属性 第二类,原子性控制 atomic nonatomic
/**
* 1、atomic,原子性,可以保证对实例变量的访问 在 多线程情况下是安全,在同一时间只允许一个线程对象去访问实例变量,相当于做了一步加锁操作。原子性控制的默认属性是atomic。
2、nonatomic,非原子性,不能保证对实例变量的访问在多线程下是安全的。但是这是我们常用的属性,因为atomic太消耗性能,需要不断的进行加锁、解锁。
*/
//{
// NSInteger _age;
//}
//@property (nonatomic, copy) Person *person;
@property (nonatomic, copy) NSString *name;
@property (nonatomic) NSInteger age;
@property (nonatomic, retain) NSString *gender;
//属性的属性第三类:语义设置,最重要的一类,这一类属性的不同,决定了属性默认实现的setter、getter方法的内部实现不同
/**
* 1、assign,assign修饰的属性,setter、getter内部实现是直接赋值和取值的。只要是基本的数据类型,都用assign修饰。assign是默认的语义设置属性。
2、retain,只要是对象类型,都可以用retain修饰。
3、copy,如果一个属性是用copy修饰的,此属性对应的类,必须接受了NSCopying协议,并且实现了协议里面的copyWithZone:方法
*/
//伪拷贝,相当于直接赋值,并没有生成新的拷贝对象。
/*
- (id)copyWithZone:(NSZone *)zone {
return [self retain];
}
*/
//真拷贝之浅拷贝
//对象是两个,共用一份内容。
- (id)copyWithZone:(NSZone *)zone {
Student *student = [[Student alloc] init];
student.name = self.name;
student.age = self.age;
student.gender = self.gender;
return student;
}
//真拷贝之深拷贝
//两个对象,两份内容。
/*
- (id)copyWithZone:(NSZone *)zone {
Student *student = [[Student alloc] initWithName:[self.name copy] age:self.age gender:[self.gender copy]];
return student;
}
*/
//copy {
// [self copyWithZone];
//}
//多态的好处 是 函数参数 可以写 父类的对象,根据自己的需求决定到底执行哪个子类的对象的方法。
void feed(Animal *animal) {
[animal eat];
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
//多态(多种形态)
//有 多态 必须 有继承。
// NSObject *s = [Dog new];
// NSObject *a = [Animal new];
Dog *dog = [Dog new];
[dog eat];
//多态的语法格式 是 父类指针指向子类对象。
Animal *animal = [Dog new];
// Dog *d = [Animal new];
//方法执行时,系统会动态检测(动态绑定)到底是什么对象。确定之后,会执行相应类内部的方法。
[animal eat];
Cat *cat = [Cat new];
feed(dog);
feed(cat);
//父类指针如果访问了子类中的私有方法,就会出现警告。
Animal *a = [Dog new];
Dog *d = (Dog *)a;
[d run];
/*
Person *person = [[Person alloc] initWithName:@"zhangsan" age:18 gender:@"男"];
NSLog(@"%@",person.car.brand);
//不要对用便利构造器创建的对象进行 release操作!!!
Person *per = [Person personWithName:@"lisi" age:19 gender:@"男"];
NSLog(@"%@",per.car.color);
// [person setName:@"lisi"];
// [person setGender:@"女"];
// [person setGender:@"妖"];
// [person.name release];
// [per release];
[person release];
*/
//集合的内存管理
/*
Person *person = [[Person alloc] initWithName:@"张三" age:18 gender:@"男"];
NSLog(@"person retainCount is %lu, %p",[person retainCount], person);
NSMutableArray *mArray = [[NSMutableArray alloc] initWithCapacity:0];
NSLog(@"mArray retainCount is %lu, %p",[mArray retainCount], mArray);
[mArray addObject:person];//当一个对象被添加到 容器里面时,会执行一次retain操作,使其引用计数加1。
NSLog(@"person retainCount is %lu, %p",[person retainCount], person);
// [person release];
// [mArray removeObject:person];//当一个对象从容器中移除的时候,会执行一次release操作。
[mArray release];//容器释放的时候,会向容器内所有的对象发送一次release消息。
NSLog(@"person retainCount is %lu, %p",[person retainCount], person);