OC语法细节

#import和#include的区别  
    1.当我们在代码中使用两次#include的时候会报错:因为#include相当于拷贝头文件中的声明内容,所以会报重复定义的错误  
      但是使用两次#import的话,不会报错,所以他可以解决重复导入的问题,他会做一次判断,如果已经导入一次就不导入了  

self :类似this关键字,代表指向该对象/类的指针常量 e.g.: self->age,[self 类方法] 
不允许子类拥有父类相同的成员变量,但可以拥有相同的方法名(重写) 
父类的声明必须放在子类声明前,实现无所谓 
调用某个方法时,优先去当前类中找,如果找不到,去父类中找 
super处在对象方法中,那么就会调用父类的对象方法 
super处在类方法中,那么就会调用父类的类方法 

如果一个类想利用另一个类,只需要将该类的.h包含,类具体实现不需要知道这就是oc中强调声明的原因(相当于一个类的简介)。
oc中类方法和对象方法可以完全相同,类方法或对象方法间可以重载。

/*

 多态

 1.没有继承就没有多态

 2.代码的体现:父类类型的指针指向子类对象

 3.好处:如果函数\方法参数中使用的是父类类型,可以传入父类、子类对象

 4.局限性:

 1> 父类类型的变量不能直接调用子类特有的方法和成员。必须强转为子类类型变量后,才能直接调用子类特有的方法

 */


#pragma mark 



一个类包括.m .h

成员变量的访问(直接通过变量名)权限

@public : 在任何地方都能直接访问对象的成员变量

@private : 只能在当前类的对象方法中直接访问           (@implementation中默认是@private,implementation中可以定义变量(没有interface只有implementation也可以开发一个类),因为implementation文件(.m)一般不被其他文件import,因此变量不可见,也就不存在访问的情况。)

@protected : 可以在当前类及其子类的对象方法中直接访问(@interface中默认就是@protected)

@package : 只要处在同一 个框架中,就能直接访问对象的成员变量

@interface和@implementation中不能声明同名的成员变量


类名和对象名是指针

id  d=[oc对象 new]  (将新对象的地址赋值给指针变量)  指向对象的指针类型等于NSObject *,利用它可以定义一个指向某个对象的指针变量

typedef struct objc_object{

   Class isa;   //objc_object是一个对象的结构,包含isa指针

}* id;

[d 对象方法]      //id类型的变量不能用点语法

类也是一个对象,是objc_class类型,简称“类对象”(变量A是类B的对象是说变量A的类型是B)
class c=[对象名或类名  class]  指向类 的指针类型 ,相当于  objc_class*, 利用它可以定义一个指向某个类的指针变量
typedef struct  objc_class*  Class;
调用:[c  类方法]


在implementation中重写原始init()

- (id) init{

  if(self=[super init]){

    成员变量初始化;

    }

   return self;

}

[类 new]==[[类 alloc] init]


在interface和implementation自定义带参数的inintwithXX()

- (id)initWithName:(NSString *)name andAge:(int)age

{

    if ( self = [super init] )

    {

        _name = name;

        _age = age;

    }

    return self;

}


 Student *p = [[Student alloc] initWithName:@"Jim" andAge:29 andNo:10];


有时候我们重写父类的init方法时不注意将init后面的第一个字母写成了小写,在这个方法里面又调用父类的初始化方法(self = [super init];)时会报错,错误信息如下:error:Cannot assign to 'self' outside of a method in the init family

原因:只能在init方法中给self赋值,Xcode判断是否为init方法规则:方法返回id,并且名字以init +大写字母开头+其他  为准则。例如:- (id) initWithXXX;

java当中的增加新功能怎么实现的?

➢ 如何在不改变原来类模型的前提下,给类扩充一些方法?有2种方式

 继承  (需要下转型)

 分类(Category)



@interface 类名 (分类名称)

// 方法声明

@end


@implementation 类名 (分类名称)

// 方法实现

@end


3. 好处

➢ 一个庞大的类可以分模块开发

➢ 一个庞大的类可以由多个人来编写,更有利于团队合作


➢ Category可以访问原始类的实例变量,但不能添加变量,只能添加方法。如果想添加变量,可以考虑通过继承创建子类

➢ Category可以实现原始类的方法,但不推荐这么做,因为它是直接替换掉原来的方法,这么做的后果是再也不能访问原来的方法

➢ 多个Category中如果实现了相同的方法,只有最后一个参与编译的才会有效




类似Java中得toString()

使用NSLog和%@(输出对象)输出某个对象时,会调用对象的-description方法,并拿到返回值进行输出

使用NSLog和%@输出某个类对象时,会调用类对象+description方法,并拿到返回值进行输出

3.     修改NSLog的默认输出

l   重写-description或者+description方法即可

4.     死循环陷阱

l   如果在-description方法中使用NSLog打印self


block变量(有点像函数指针)

 int (^sumBlock)(int, int)=

^(int a, int b) {

    return a + b;

 };


  void (^myBlock)()=

 ^() {

    NSLog(@"----------");

 };

 

 * block内部可以访问外面的变量

 * 默认情况下,block内部不能修改外面的局部变量

 * 给局部变量加上__block关键字,这个局部变量就可以在block内部修改

 

 4> 利用typedef定义block类型

 typedef int (^MyBlock)(int, int);

 // 以后就可以利用MyBlock这种类型来定义block变量

 MyBlock b1, b2;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值