IOS简单笔记

来源:互联网 发布:java pop3 编辑:程序博客网 时间:2024/06/05 00:52
@synthesize 关键字的介绍以及用法


@synthesize 方法名
注意:
方法名一定要现在.h中使用@property int 方法名 




表示生成.h变量中@property


@property 编译器指令编译器帮我们进行_age _name 的get/set方法是声明


@synthesize 帮我们实现了实例变量的get和set方法


@synthesize age; 帮我们生成了一个变量age
   相当于实现了,原来实例变量是空的
     -(void)setAge: (int)age{
             self->age = age;        
             }


     -(int)age{
         return age;
                }


person *p = {Person new}
p.age = 18;
p.name = @"啊啊啊"
NSLog(@"%d",p.age);








@synthesize 指定实例变量复赋值
@synthesize 方法名 = 实例变量名
当指定实例变量名以后,此时再不会生成也不会操作默认的实例变量了


.h中
int _age;
int _weight;


@property int weight;




.m中


@synthesize age;
@synthesize weight;
或者
 如果两个实例变量的类型一致 可以
@synthesize age,weight;


@synthesize age = _age;
/*
    -(void)setAge:(int) age{
          _age = age;
             }




     -(int)age{
          return _age;
          }
*/






@property增强使用
Xcode 4.4之后:可以只使用@property而不使用@synthesize
声明和实现了  _age ,_name 的 get和set 方法  操作的是带有下划线的实例变量
如果当前类没有下划线的实例变量,则系统会帮我们生成(如果自动生成则是私有的,相当于
对于子类都是隐藏的)


@property int age;   //生成了一个int _age;
@property NSString *name;  //生成一个  NSString *_name; 






@property 增强下重写get和set方法:   
在,M中只能重写一个,不然会报错,如果要重写可以用@synthesize
在.m 中手动实现 set方法


-(void)setAge:(int)age{
      if(age>0){
       _age = age;
    }else
      _age = 0;
}




-(void)setName:(NSString *)name{
   //如何判断字符串不为空   length
      if([name length] > 0){
        _name = name;
       }else {  NSLog(@"name不能为空");  }
}










动态类型和静态类型
多态:允许不同的类定义相同的方法,当父类指针指向不同子类会调用不同子类的同名方法
动态类型: 程序直到执行的时候才能确定所属的类
静态类型:将一个变量定义为特定类的对象就是静态类型


person *p = [person new];
animal *ani = {dog new};
[ani run];   //调用的狗的run 方法 






id类型以及应用场景


1.  NSOject访问子类的方法 
   animal : NSObject
   dog : animal


animal: -(void)run;
dog:  -(void)run;




animal *ani = [animal new];
[ani run];  //动物跑


animal *an2 = [dog new]
[an2 run];   //狗跑


//NSObject 访问子类特有的方法run
NSObjcet *obj = [animal new];
[(animal*)obj run];   //  动物跑


obj = [dog new];
[(dog*)obj run];   // 狗跑






NSObject 是所有类的基类  NSObject可以指向任何子类
NSObject 和 id都可以指向任何对象 但是object会进行编译检查需要进行强制类型转换
id不需要强制类型转换 直接用就可以了
编译器看到id以后认为id是动态类型 直接跳过不检查id的类型


id类型是一种通用的对象类型可以用来存储任何类的对象,可以理解为万能指针




id类型应用场景:


id obj2 = ani;
[onj2 run];


id obj = [ainimal new];
[obj run];




动态类型检测:


1动态绑定:在OC 中一个对象类是否调用指定的方法不是编译器决定二十由运行时决定,这就是动态绑定


2动态类型检测方法:


 判断类型:判断实例对象是否是这个类或者这个类的子类的实例
    -(BOOL) isKindOfClass:classObj


BOOL b = [animal isKindOfClass:[animal class]];
NSLog(@"b = %d",b);




-(BOOL) isMemberOfClass:classObj 判断是不是这个类的实例,不管是不是这个类的子类的实例


-(BOOL) isSubOfClass:ClassObj 判断是不是某个类的子类(此方法参数必须是类 不是对象)
例如: isSub = [[dog class]isSubOfclass:[Animal class]];
                  Dog                      ani class
          




动态类型检测第二部分: 
1 方法响应的检测:
判断对象能否响应指定的方法:


animal *ani = [animal new];  //animal中没有eat方法 如果是[dog new] 则可以


//判断如果ani 能调用eat方法就调用,不能调用就不用
[(dog *)ani eat];




/*
这样写 
    if(isrespond){    [(dog *)ani eat]; }
   else{ NSLog(@"不能调用");  }
*/




-(BOOL) respondsToSelector:selector 判断实例是否有这个方法能响应


1,判断实例对象能否响应(调用)指定的方法
格式:  [对象 respond...:方法的SEL];


SEL s1 = @selector(eat);   //把eat包装成sel类型
BOOL isrespond = [ani respondsToSelector:s1];
NSLog(@"isrespomd = %d",isrespond)






2 判断类是否有这个方法,  此方法是类方法,不能用在类的对象
格式:    


 +(BOOL)instancesRespondToSelector:


SEL s1 = selector(run);
BOOL b = [Dog instancesRespondToSelector:s1];
NSLog(@"b = %d",b);




响应方法:


Animal *ani = [Animal new];
if([ani respondsToSelector:@selector(eat)] == YES) {
   // [(Dog *)ani eat];
   [ani performSelector:@selector(eat)];  //响应方法
}
else { NSlog(@"...");}




通过performSelector响应有参的方法


SEL s2 = @selector(eat:);
[ani performSelector:s2 withObject:@"我我我"];






构造方法:用来初始化对象的方法就是构造方法


OC 中给对象进行初始化的方法就是init 该方法是一个对象方法 
该方法返回的是一个对象(调用当前init方法的对象)




super的使用:
Dog *dog = [Dog new];
[dog run];
//执行顺序: 子类——父类——父类的父类...NSObject
//假设有需求 要动物跑 则在子类的方法中调用父类的run方法
//则在狗的run 方法中写一句
[super run];  // super指代的就是父类对象




重写构造方法:
//当子类把父类的init覆盖了,默认的先执行子类的


-(instancetype) init{
   self = [super init]; //先让父类把原来做的事情做完
   //判断父类是否初始化成功
     //self赋值为[super init]是为了防止父类的初始化方法释放掉了
self指向的空间并重新分配了一块空间
if(self){  _age = 10; } 
return self;
}




//创建学生类
在学生.m文中重写


-(instancetype)init{
  //1 初始化父类   如果不写 self = [super init]; 则age不会是10
  //2 判断是否初始化成功
  //3 初始化当前实例变量
  //4 retun self
if(self == [super init]){ _sno = 1;}
return self;
}




重写构造方法的应用场景:
有20个特种兵,每个兵都一把枪,随时都可以开火
类:大兵{开火}  枪{子弹,射击}




大兵类.m文件重写构造方法:


-(instancetype)init{
if(self == [super init];){
Gun *gun = [Gun new];
gun.bulltecount = 3;
_gun = gun;
}
return self;
}








自定义构造方法:
规范:  1 一定是对象方法 以减号开头
2 返回值一般是id类型
3 方法名一般以initWith开头


例子需求:当person类创建成功后给人起一个名字,用指定的值进行初始化
          创建学生类的时候指定姓名,年龄,学号
Person .h中
@property NSString* name;
@property int age;


自定义构造方法:
-(instancetype)initWithName:(NSString *)name andAge:(int) age;
{
if(self == [super init]){
_name = name;
_age = age;
}
return self;
}






main中
Person *p = [[Person alloc] initWithName:@"啊啊"andAge:18];
NSLog(@"%d,%@",p.age,p.name);




Student:Person
学生类.h中


@property int sno;
-(instancetype)initWithName:(NSString *)name andAge:(int) age andSno:(int) sno;
{
if(self == [super initWithName:name andAge:age]){
_sno = sno;
}
retutn self;
}




创建学生对象:
Student *stu = [[Student alloc]initWithName:@"小明"andAge:18andSno:430];

NSLog(@"%d,%d,%@",stu.age,stu.sno,stu.name);






内存管理:


栈: 局部变量:定义在方法内部的变量,由系统管理
堆: 动态存储区 一般情况下由程序员进行管理


引用计数器:
/*
   如果内存管理不当:
1.不再使用的对象没有被回收,内存泄露,程序崩溃
2.正在使用的对象被释放,导致野指针的错误,程序崩溃


   ARC Automatic Reference Counting 自动引用计数
   MRC Manual Reference Counting 手动引用计数




   1.当一个对象被创建出来的时候,这个对象的引用计数是1
   2.当对象当中的引用计数是0的时候,系统会立即回收


   3.release   引用计数 -1
   4.retain    引用计数 +1


*/


 Person *p = [[Person alloc] init];
 long count = [p retainCount];
  NSLog(@"%d",count);  /输出1 


  [p retain];   //引用计数为2 
  [p release];   //retaincount = 0


  p = nil;    // p 指向 nil,为空指针,给空指针发消息不会报错
 //NSLog(@"%d",[p retainCount]);  就不会报错


//永远不要试图自己调用此方法,由系统调用
-(void) dealloc{
//这个方法必须调用父类的改方法,并且必须放在最后
[super dealloc];
}






多个对象的内存管理:
 手动内存管理的黄金法则:
 谁调用了new,alloc,retain,copy,multabCopy,谁就要调用release 或autoreleas
 当你需要一个对象的时候就发送一条retain的消息,
 当你不需要一个对象的时候就发送一条release消息
 当你要接受一个新对象的时候,需要release旧对象 retain新对象
 如果新对象与旧对象是一个对象就不需要内存管理代码


Person *p = [[Person alloc] init];
Room *r = [[Room alloc] init];
p.room = r;
[r release];



























































0 0
原创粉丝点击