1.ARC
1.IOS 5.0 开始使用,到IOS 7.0强制使用
2.在ARC中,不允许程序员调用retain、release、dealloc、autorelease,由编译器自动添加其调用的语句
void test1()
{
CZPoint *p=[[CZPoint alloc]initWithX:10 andY:20];
[p show];
//[p release]; 在ARC中,不需要手动编写此句
} //首先ARC自动添加[p release]; 再将指针释放
void test2()
{
CZPoint* p1=[[CZPoint alloc]initWithX:10 andY:20];
[p1 show];
CZPoint* p2;
p2=p1;
// [p2 retain]; //ARC中不允许手动调用retain,ARC将自动添加
[p2 show];
}//ARC自动添加[p1 release]; 和 [p2 release];
void test3()
{
CZPoint *p1=nil;
{
CZPoint *p2=[[CZPoint alloc]initWithX:10 andY:20];
[p2 show];
p1=p2; //ARC自动添加了[p1 retain];
}//ARC自动添加了[p2 release];
[p1 show];
}//ARC自动添加[p1 release];
void test4()
{
CZPoint *p1=[[CZPoint alloc]initWithX:10 andY:20];
{
CZPoint *p2=[[CZPoint alloc]initWithX:30 andY:40];
[p2 show];
p1=p2; //在此句执行之前,ARC首先自动添加[p1 ralease];在执行此句之后ARC又自动添加了[p1 retain]
}//ARC自动添加[p2 release];
[p1 show];
}
3.ARC中新关键字
3.1 __srong 强引用(默认方式)
3.2 __weak 弱引用,ARC不会自动添加[p1 retain];当指向的空间被释放的时候,会将指针清零。
3.3 __unsafe_unretain 和弱引用一样,但是不会清空指针。
3.4__autoreleasing 放入自动释放池
void test5()
{
__weak CZPoint *p1=nil;
{
CZPoint *p2=[[CZPoint alloc]initWithX:10 andY:20]; //默认为强引用__strong CZPoint
[p2 show];
p1=p2; //p1是弱引用,ARC不会自动添加[p1 retain];
p1=p2;
NSLog(@"%p",p1);
}//ARC自动添加[p2 release];还将弱指针自动p1清空,即自动添加p1=nil;
NSLog(@"---------");
NSLog(@"%p",p1);
}
void test6()
{
__weak CZPoint *p=[[CZPoint alloc]initWithX:10 andY:20];
//在ARC中,alloc出来的堆空间的堆空间,必须由强指针指向(持有),当ARC发现没有强指针指向该空间时,ARC将会把该空间释放。
NSLog(@"%p",p); //会输出空指针
}
void test7()
{
CZPoint *p=[[CZPoint alloc]initWithX:10 andY:20];
[p show];
CZCircle *c=[[CZCircle alloc]init];
c.center=p;
c.radius=5;
}//ARC自动添加了[p release];、[c.center release]和[c release];
void test8()
{
__unsafe_unretained CZPoint *p1=nil;
CZPoint *p2=[[CZPoint alloc] initWithX:10 andY:20];
[p2 show];
p1=p2;
NSLog(@"%p",p1);
NSLog(@"---------");
NSLog(@"%p",p1); //和弱引用一样,但是不清空指针
}
4.ARC与MRC混编, Edit->convert->ToObjective-C ARC....
2.NSObject
1.是所自定义类的根类
2.创建方法 alloc init new ..... ( [CZDog new] 等价于 [[CZDog alloc]init];
3 copy
浅拷贝:一个指针释放另一个指针失效,但是节省空间
CZDog *dog=[[CZDog alloc]init]
__weak CZDog *dog1;
dog1=dog; //dog1不持有空间
引用计数拷贝:一个指针释放了另一个指针不受影响,同时避免了浅拷贝和深拷贝的缺点
CZDog *dog=[[CZDog alloc]init];
CZDog *dog1;
dog1=dog; //dog1 持有空间
深拷贝:两个指针互不干扰,但是占用空间大
int *p1=(int*)malloc(4);
*p1=10;
int *p2=(int*)malloc(4);
*p2=*p1 //两个指针各自有自己的空间
3.1 自定义类实现深拷贝时,需要采纳NSCopying协议
@interface CZInteger : NSObject<NSCopying>
@property int integer;
-(id)initWithInteger:(int)integer;
+(id)integerWithInteger:(int)integer;
-(void)show;
@end
3.2 在自定义类中的.m文件中实现NSCopying协议中的方法copyWithZone
@implementation CZInteger
-(id)initWithInteger:(int)integer
{
if(self=[super init])
{
self.integer=integer;
}
return self;
}
+(id)integerWithInteger:(int)integer
{
__autoreleasing CZInteger *p=[[CZInteger alloc]initWithInteger:integer];
return p;
}
-(void)show
{
NSLog(@"%d",self.integer);
}
-(id)copyWithZone:(NSZone *)zone
{
CZInteger *i=[[CZInteger allocWithZone:zone]initWithInteger:self.integer];
return i;
}
@end
3.3 在主函数中,用copy方法实现深拷贝,该方法在函数体重会自动调用copyWithZone
#import <Foundation/Foundation.h>
#import "CZInteger.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
CZInteger *i1=[CZInteger integerWithInteger:10];
CZInteger *i2=[i1 copy]; //调用copy实现深拷贝
[i2 show];
NSLog(@"%p",i1);
NSLog(@"%p",i2);
i2.integer=20;
[i1 show];
}
return 0;
}
3.4 copy 可以作为property的参数,使属性赋值时得到的是副本
#import "CZBook.h"
@interface CZStudent : NSObject
@property int age;
@property(copy) CZBook *book; // copy 可以作为property的参数,CZBook类要支持深拷贝
-(void)study;
#import "CZStudent.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
CZBook *b=[[CZBook alloc]initWithName:@"ddd" andPrice:20];
CZStudent *stu=[[CZStudent alloc]init];
stu.age=18;
stu.book=b; //自动实现深拷贝
NSLog(@"%p",b);
NSLog(@"%p",stu);
b.price=100;
[stu study];
}
return 0;
}
3.类对象
1.类对象不是类的对象
2是一种数据,用来在OC中唯一标识一个类
3.该种数据的数据类型是Class
4.该种数据调用class方法获取
#import <Foundation/Foundation.h>
#import "CZStudent.h"
#import "CZTeacher.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
CZStudent *stu=[CZStudent StudentWithName:@"小明" andAge:18];
//stu是类的对象
Class c=[stu class]; //变量c是一个类对象
Class c1=[CZStudent class]; //class方法即是实例方法又是类方法,实例方法与类方法可以同名
if(c==c1)
{
NSLog(@"对象stu是类CZStudent的对象");
}
if([stu class] == [CZTeacher class])
{
NSLog(@"对象stu是类CZTeacher的对象");
}
}
return 0;
}
5 类信息比较
5.1 isKindOfClass:判断某个对象是否为指定类的对象
#import "CZSquare.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
CZSquare *p=[[CZSquare alloc]init];
if([p isKindOfClass:[CZSquare class]]==YES)
{
NSLog(@"p是类CZSquare的对象");
} //判断是指定类的对象
if([p isKindOfClass:[CZRectangle class]]==YES)
{
NSLog(@"p是类CZRectangle的对象");
} //还可以判断是指定类父类的对象
if([p isKindOfClass:[NSObject class]]==YES)
{
NSLog(@"p是类NSObject的对象");
} //还可以判断是父类的父类的对象
}
return 0;
}
5.2 isMemberOfClass: 判断某个对象是否为指定类的对象(与父类无关)
if([p isMemberOfClass:[CZSquare class]]==YES)
{
NSLog(@"对象p是类CZSquare的对象");
}
if([p isMemberOfClass:[CZRectangle class]]==YES)
{
NSLog(@"对象p是类CZSquare的对象");
}
5.3 isSubclassOfClass: 判断某个类是否为指定类的子类
if([CZSquare isSubclassOfClass:[CZRectangle class]]==YES)
{
NSLog(@"类CZSquare是累CZRectangle的子类");
}
if([CZPoint isSubclassOfClass:[CZRectangle class]]==YES)
{
NSLog(@"类CZPoint是累CZRectangle的子类");
}