1.)NSString、NSArray、NSDictionary 等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary;
copy此特质所表达的所属关系与strong类似。然而设置方法并不保留新值,而是将其“拷贝” 意思就是进行了深拷贝了,在内存中存在两份地址,而不仅仅是对其值得拷贝
此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变” (immutable)的字符串,确保对象中的字符串值不会无意间变动
只要实现属性所用的对象是“可变的” (mutable),就应该在设置新属性值时拷贝一份。
2.Nsarray用copy(正确的修饰)修饰和strong的区别
1.用copy修饰
被copy修饰之后,源对象数组被copy了一份,源对象数组和副本对象数组是不同的,所以副本对象数组并不会随着源对象数组改变。(此时是深拷贝) 即使copy的原对象是个可变数组的时候,进行更删改查,也不会造成crash
2假如用strong修饰的时候
被strong修饰之后,由于只是强引用,所以副本对象数组和源对象数组只是指向同一个内存区域,这样就会造成副本对象数组跟着原数组是同一个地址内存,一旦原数组是可变数组而且进行更删操作,就会造成crash
3.NSMutableArray 被copy、strong(正确的修饰)修饰后的变化
[把NSMutableArray用copy修饰有时就会crash]
因为对这个数组进行了增删改操作,而copy后的数组变成了不可变数组NSarray
如果用strong修饰 相对于赋值 是引用新值,可变数组类型不会改变 还是可变数组
OC的set和get方法
.h的声明
- (void)setAge:(int)age;
- (int)age;
.m 的实现
// 成员变量_age的set和get方法的实现
- (void)setAge:(int)age
{
_age = age;
}
- (int)age;
{
return _age;
}
4空指针和野指针
1.空指针
1> 没有存储任何内存地址的指针就称为空指针(NULL指针)
2> 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0。
野指针
"野指针"不是NULL指针,是指向"垃圾"内存(不可用内存)的指针。野指针是非常危险的。
1 Student *stu = [[Student alloc] init];
假设Student对象的地址为0xff43,指针变量stu的地址为0xee45,stu中存储的是Student对象的地址0xff43。即指针变量stu指向了这个Student对象。
[stu setAge:10];
这行代码的意思是:给stu所指向的Student对象发送一条setAge:消息,即调用这个Student对象的setAge:方法。目前来说,这个Student对象仍存在于内存中,所以这句代码没有任何问题。
[stu release];
这行代码的意思是:给stu指向的Student对象发送一条release消息。在这里,Student对象接收到release消息后,会马上被销毁,所占用的内存会被回收。
[stu setAge:10];
Student对象被销毁了,地址为0xff43的内存就变成了"垃圾内存",然而,指针变量stu仍然指向这一块内存,这时候,stu就称为了野指针!
这句代码的意思仍然是: 给stu所指向的Student对象发送一条setAge:消息。但是在执行完第5行代码后,Student对象已经被销毁了,它所占用的内存已经是垃圾内存,如果你还去访问这一块内存,那就会报野指针错误。这块内存已经不可用了,也不属于你了,你还去访问它,肯定是不合法的。所以,这行代码报错了!
所有必须手动置空
stu = nil;
stu变成了空指针,stu就不再指向任何内存了
因为stu是个空指针,没有指向任何对象,setAge:消息是发不出去的,不会造成任何影响。当然,肯定也不会报错。
.堆和栈的区别?
栈区(stack)--由编译器自动分配释放,存放函数的参数值、局部变量的值。先进后出
堆区(heap)--一般由程序员分配释放。先进先出
iOS本地数据存储都有哪几种方式
1.Write写入方式:永久保存在磁盘中。只支持NSString、NSData、NSArray、NSDictionary。
2.NSKeyedArchiver(归档)采用归档的形式来保存数据,该数据对象需要遵守NSCoding协议
3.SQLite(FMDB)注意FMDB不是数据库, 而是一个SQLITE管理框架.
4.plsit文件存储