自学了一个多月的IOS,对Object-C也有了初步的认识,也有很多观点不知道是否正确,所以整理了一下,和小伙伴们分享分享

1.OC中使用的消息机制代替调用方法

区别:使用消息结构的语言,其运行时缩引执行的代码是由环境来决定的,而函数调用的语言则是用编译器来决定的

2.对象等同性

判断两个对象是否想同,不要使用 ==操作符来判断,因为该操作符比较的是两个指针本身,而不是指针所指的对象,应该用NSObject协议中声明的isEquel方法来判断两个

对象的等同性!两个不同的对象总是不想等的!

 NSString *oneStr = @"abc123";
NSString *twoStr = [NSString stringWithFormat:@"abc%i",];
BOOL equalA = (oneStr == twoStr);//NO
BOOL equalB = [oneStr isEqual:twoStr];//YES
BOOL equalC = [oneStr isEqualToString:twoStr];//YES

判断两个对象等同性的关键方法
    (BOOL)isEqual:(id)object;
    @property (readonly) NSUInteger hash;

注意:

  • 若想监测对象的等同性,提供isEqual:与 hash 方法

  • 相同的对象必须具有相同的哈希码,但是两个哈希码相同的对象却未必相同

  • 不要盲目逐个检测每条属性,而是应该依照具体需求来制定监测方案

  • 编写 hash 方法时,应该是用计算速度快而且碰撞低的算法

3.setter 方法 getter 方法

setter 方法:
               》1.一定是对象方法
               》2.一定没有返回值
               》 3.方法名称一定以set开头,后面要设置的属性去掉下划线,首字母大写
               》 4.一定要有参数,参数的类型需要和设置的属性类型一致,并且参数名称就是属性名称去掉下划线
   getter 方法:
               》1.一定是对象方法
               》2.一定有返回值,且返回值类型一定与属性类型一致
               》 3.方法名称就是属性名称去掉下划线
               》4.一定没有参数

4.继承

》1,子类方法名和父类方法名相同,我们称之为方法重写
              》2,对象方法和类方法都可以重写
              》3,成员变量不能重写

》何时使用继承?
                          XXX是xxx 或者 XXX is a xxx

》 [super 方法名]/[self 方法名]

supper 指定调用父类的方法

self:先在子类中查找,再在父类中查找
                         supper:直接在父类中查找

5.多态:父类指针指向子类对象

6.动态类型(id):在编译的时候只会检查当前类型对应的类中有没有需要调用的方法,在运行时,才会判断它的真实类型! 动态数据类型一般用于多态

7.构造方法

》[Person new]和[[Person alloc]init]的区别

他们两基本相同,只是 new初始化只能调用init方法,init初始化的时候能调用其他方法;

》new 做了三件事

1.开辟存储空间 +alloc方法
              2.初始化所有的属性(成员变量) -init方法
              3.返回对象地址

》动态数据类型与静态数据类型的区别

8.重写init 方法

》注意:必须按照苹果的规定格式来,否则会引发错误

1.必须先初始化父类,再初始化子类
             2.必须判断父类是否初始化成功,只有父类初始化成功,才能继续初始化子类
             3.返回当前对象的地址

4.instancetype只能作为返回值类型,不能作为形参和变量类型

5.为什么不使用ID?因为ID是动态类型,程序在编译时不会检查类型,而在运行时检查,为了使程序编译时发现错误,使用了instancetype

不带参数初始化:

 -(instancetype)init
{
self=[super init];//先初始化父类
if (self!=nil) {//必须判断父类是否初始化成功
_age=;
}
return self;
}

带参数初始化

 //initWithAge W要大写 属性名称不要以new开头,否则有可能引发未知错误,方法名也不要以new开头
-(instancetype)initWithAge:(int)age WithName:(NSString *)name
{
self=[super init];
if (self!=nil) {
_age=age;
_name=name;
}
return self;
}

9.自定义类工厂方法

》自定义类工厂方法是苹果的一个规范,一般情况下,我们会给一个类提供自定义构造方法和自定义类工厂方法用于创建一个对象

》提供对象方法 叫做构造方法
            》提供类方法 叫做类工厂方法

         Person*p=[Person person];
p.age=;
NSLog(@"%i",p.age);
Person *p2=[Person personWithAge:];
NSLog(@"%i",p2.age);
 /*
》什么是类工厂方法:
用于快速创建对象的类方法,我们称之为类工厂方法
类工厂方法主要用于 给对象分配存储空间和初始化这块存储空间 》规范:
1.一定是类方法 +
2.方法名称以类名开头,首字母小写
3.一定有返回值,返回值是 id/instancetype
*/
@interface Person : NSObject
@property int age;
//定义一个无参数类工厂方法
+(instancetype)person;
//带参数的类工厂方法
+(instancetype)personWithAge:(int)age;
 @implementation Person
//实现无参数类工厂方法
+(instancetype)person
{
return [[self alloc]init];//这里最好使用self来调用,否则有继承关系时会出错 }
+(instancetype)personWithAge:(int)age
{
Person *p= [[self alloc]init];
p.age=age;
return p;
}
@end

10.类的本质

》1. 类其实也是一个对象,这个对象会在这个类第一次被使用时创建

2.只要有了类对象,将来就可以根据类对象来创建实例对象

3. 实例对象中有一个isa指针,指向创建自己的类对象

》 类对象中保存了当前对象所有的对象方法

当给一个实例对象发送消息时,会根据实例对象中的isa指针去对应的类对象中查找

         Person *p1=[[Person alloc]init];
Person *p2=[[Person alloc]init];
//1.如何创建类对象
//[实例对象 class],[类名 class]
//一个类在内存中只有一个类对象
Class c1=[p1 class];
Class c2=[p2 class];
Class c3=[Person class];
NSLog(@"c1:%p,c2:%p,c3:%p",c1,c2,c3);//结果 c1:0x100001140,c2:0x100001140,c3:0x100001140 //2.类对象的应用场景
//》1.用于创建实例对象
Person *p3=[[Person alloc]init];
//》2.用于调用类方法
[p3 test];

11.load和initialize方法何时加载

 /*
只要程序启动,就会将所有类的代码加载到内存中,放到代码区
load方法会在当前类被加载到内存的时候调用,有且只调用一次
如果存在继承关系,会先调用父类的load方法,再调用子类的load方法
*/
+(void)load
{
NSLog(@"类第一次被加载的时候调用");
} //当前类第一次被使用的时候调用(也会是创建类对象的时候)
//initialize在整个程序的运行过程中只会调用一次,不管这个类被使用了多少次,都只会调用一次
//initialize用于对某个类一次性的初始化(如果有些东西只需要做一次,就把这些东西写在initialize里面)
//如果存在继承关系,会先调用父类的initialize方法,再调用子类的load方法
+(void)initialize
{
NSLog(@"类第一次被使用时调用了");
}

12.SEL

 int main(int argc, const char * argv[]) {
@autoreleasepool {
//》SEL类型的第一个作用,配合对象/类来检查对象/类中有没有实现某一个方法
SEL sel=@selector(setMyage:);
Person *p=[[Person alloc]init];
//》判断person 中有没有setMyage:这个方法,如果有,就会返回true(1),如果没有,就会返回false(0)
//》respondsToSelector 如果通过对象来调用该方法,则会判断对象中有没有实现-号开头的方法
//》 如果通过类来调用该方法,则会判断该类中有没有实现+号开头的方法
BOOL b= [p respondsToSelector:sel];
NSLog(@"b:%i",b);
BOOL c= [p respondsToSelector:@selector(test)];
NSLog(@"b:%i",c);
BOOL d= [Person respondsToSelector:@selector(test)];
NSLog(@"b:%i",d);
//》2.SEL类型的第二个作用:配合对象/类来调用某一个SEL方法
[p performSelector:@selector(demo)];
//》withObject需要传递参数,
//注意:参数必须是对象类型,也就是说方法的形参必须是对象类型,因为withObject只能传递对象,否则会报错
//withObject最多只能传递2个参数
[p performSelector:@selector(demo:)withObject:@""]; //》3.SEL类型的第三个作用:
//配合对象 将sel对象作为方法的形参
Car *car=[[Car alloc]init];
SEL selcar=@selector(run);
Person *pp=[[Person alloc]init];
[pp makeObject:car andSel:selcar]; }
return ;
}

13.内存管理

》只要一个对象被释放了,我们就称为这个对象为“僵尸对象”

》当指针指向一个僵尸对象,我们就称这个指针为野指针
               》只要给一个野指针发送消息就会报错
               》 空指针:没有指向存储空间的指针 nil 0
               》为了避免给野指针发送消息会报错,一般情况下,当一个对象被释放后我们会将这个对象的指针设置为空指针
               》在OC中给空指针发送消息不会报错

》当A对象使用B对象时,一定要对B对象进行一次retain,这样才能保证A对象存在时,B对象也存在,也就是说,无论什么时候,A对象都可以使用B对象

当A对象释放时,一定要对B对象进行一次release,这样才能保证A对象释放时,B对象也会被释放,避免内存泄露!

》例如Person对象使用Room对象:

 #import "Person.h"

 @implementation Person
-(void)setRoom:(Room *)room
{
if (_room!=room) {//判断传入的对象是否与当前对象一样
[_room release];//release以前的对象
//retain传入的对象
_room=[room retain];//retain 不仅会让引用计算器+1,还会返回当前对象
} }
-(void)dealloc
{
[_room release];
NSLog(@"%s",__func__);
[super dealloc];
}
@end

14.分类-Category

》方法分为:方法的声明,方法的实现,所以通过某个类扩充方法,也分为方法的声明和方法的实现

》分类的作用:

1.可以在不修改原有类的基础上,给这个类扩充一些方法

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

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

》注意点:

1.分类是给原有类扩充方法的,它只能添加方法,不能添加属性

2.分类中使用@property,只会生成getter和setter的声明,不会生成实现,以及私有的成员变量

3.可以在分类中访问原有类的.H文件

4.一个类可以有很多分类

5.如果在分类中有和原有类重名的方法,会先调用分类中的方法,也就是说会忽略原有类的方法

6.如果多个分类都有重名的方法,那么执行谁是由编译器决定,谁最后被编译,就执行谁(在开发中尽量不要写重名的方法)

7方法的调用顺序:分类-->子类-->父类

15.Block

》1.block可以访问外界的变量
          2.block中可以定义和外界同名的变量,如果和外界定义的是同名的对象,那么在block访问的是Block中的变量
          3.默认情况下不可以在block中修改外界变量的值
            因为block和外界的变量不是同一个变量
            如果block中访问到外界的变量,block会将外界的变量copy一份到堆内存中
            因为block中使用的外界的变量是copy的所以调用之前修改外界的变量是不会影响到block中copy的值
         4.如果想在block中修改外界变量的值,必须在外界变量前加_block,

》block是存储在堆中还是栈中?
         默认情况下是存储在栈中,如果对block进行copy,block会转移到堆中
        如果在栈中,block访问了外界的变量,那么不会对对象进行retain操作
        但如果在堆中,block访问了外界的变量,那么会对对象进行一次retain操作

  //block和函数一样,可以没有返回值也没有形参,也可以有
//void(*roseBlock)();指向函数的指针
void(^roseBlock)(int);//定义一个block
roseBlock= ^(int num){
for (int i=; i<=num; i++) {
printf(" {@}\n");
printf(" |\n");
printf(" \\|/\n");
printf(" |\n");
}
};
//要想执行block保存的代码,必须调用
roseBlock();
//无返回值,有参数
void(^testBlock)(int)=^(int num)
{
for (int i=; i<num; i++) {
NSLog(@"---");
}
};
testBlock();
//有返回值,有参数
int(^sumBlock)(int,int);
sumBlock=^(int value1,int value2){
return value1+value2;
};
NSLog(@"sun:%i",sumBlock(,));

16:协议protocol

》协议的注意点:

1.协议只能声明方法,不能声明属性
       2.父类遵守某个协议,子类也会自动遵守这个协议
       3.在OC中一个类可以继承多个协议
         但OC中的类只能有一个父类,也就是说OC中的类只有单继承(支持多层继承,不支持多继承)
      4.OC中的协议可以遵守其他协议

 #import <Foundation/Foundation.h>

 @protocol SportProtocol <NSObject>
//注意:如果没有任何修饰符修饰协议中的方法,默认情况下是@required(必须实现) 如果没有实现,则会报警告
//如果协议中的方法是@optional 如果遵守该协议的类,没有实现该方法,则不会报警告
//@required @optional仅仅是程序员之间的交流,不能控制是否一定实现该方法
@required
-(void)playFootball;
-(void)playBaskball;
@optional
_(void)play; @end

IOS交流群:5883244

Object-c的一些基本概念的更多相关文章

  1. Object.prototype和Function.prototype一些常用方法

    Object.prototype 方法: hasOwnProperty 概念:用来判断一个对象中的某一个属性是否是自己提供的(主要是判断属性是原型继承还是自己提供的) 语法:对象.hasOwnProp ...

  2. Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO的概念

    PO(persistant object) 持久对象 在 o/r 映射的时候出现的概念,如果没有 o/r 映射,没有这个概念存在了.通常对应数据模型 ( 数据库 ), 本身还有部分业务逻辑的处理.可以 ...

  3. Java中PO、DO、TO、DTO、 VO、 BO、POJO 、DAO的概念

    本文系转载-原创@HollisChuang :http://www.hollischuang.com/archives/553 1.PO(persistant object) 持久对象   在 o/r ...

  4. Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO的概念(转)

    PO(persistant object) 持久对象 在 o/r 映射的时候出现的概念,如果没有 o/r 映射,没有这个概念存在了.通常对应数据模型 ( 数据库 ), 本身还有部分业务逻辑的处理.可以 ...

  5. (1)Object类 (2)包装类和数学处理类 (3)String类

    1.Object类1.1 基本概念 java.lang.Object类是Java类层次结构的根类,任何类都是Object类的直接/间接子类. 1.2 常用的方法(重点) Object() - 无参构造 ...

  6. Object的原型拷贝-create、assign、getPrototypeOf 方法的结合

    一.实现原型拷贝 1.1.代码         tips:为了体现原型链,写了继承实现的代码,这部分可跳过- <script> /* 创建包含原型链的实验对象obj1-- start */ ...

  7. Java中 实体类 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO的概念

    PO(persistant object) 持久对象 在 o/r 映射的时候出现的概念,如果没有 o/r 映射,没有这个概念存在了.通常对应数据模型 ( 数据库 ), 本身还有部分业务逻辑的处理.可以 ...

  8. java对象 Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO的概念

    PO(persistant object) 持久对象 在 o/r 映射的时候出现的概念,如果没有 o/r 映射,没有这个概念存在了.通常对应数据模型 ( 数据库 ), 本身还有部分业务逻辑的处理.可以 ...

  9. Java中POJO及其细分XO、DAO的概念

    各层命名规约: A) Service/DAO 层方法命名规约 1) 获取单个对象的方法用 get 做前缀. 2) 获取多个对象的方法用 list 做前缀. 3) 获取统计值的方法用 count 做前缀 ...

  10. Java中PO、DO、DTO、 VO、 BO、POJO 、DAO、TO的概念

    1.  PO(persistant object) 持久对象 在 O/R 映射的时候出现的概念,如果没有 O/R 映射,没有这个概念存在了. 通常对应数据模型 ( 数据库 ), 本身还有部分业务逻辑的 ...

随机推荐

  1. Struts2六、为应用指定多个配置文件

    为了使用Struts.xml更简洁,更利于维护,我们可以把Struts.xml要配置的Action信息分类别放在其他的XML文件中,使用include在struts.xml中加载这些文件: 将Web. ...

  2. 可用的CSS文字两端对齐

    最近在工作项目中接触到Web界面设计的问题,要实现文字两端对齐的效果.在网上搜索了一下,用的都是类似的技巧: text-align:justify;text-justify:inter-ideogra ...

  3. iOS动画技术笔记

    概述 在IOS开发中,实现动画操作的地方有很多,典型的是在视图控制器的segue操作时.在同一个视图控制器类中,加载切换不同的视图时,也需要动画效果,还有一些视图对象有动画效果会更好. 插一句,在IO ...

  4. hdu 2054 A == B ? (java)

    问题: 考虑问题不周到.没有考虑到可能是小数并且存在 1.0=1.01=1的情况. 本题使用了BigDecimal类,此类适用于高精度的数此时攻克了小数和01=1的问题, 该类比較方式中n.equal ...

  5. 【小白的java成长系列】——java ide 开发工具eclipse的操作

    今天看了一下自己的博客文章,里面的内容还是比較杂的,有好多技术,有好多语言,都没有突出自己的强项,能够说,从博客里面,看不出我究竟是做哪块的..加上今天被授予了博客准专家勋章,自己想了一下,还是得梳理 ...

  6. Android dump .so 文件crash log

    众所周知,在android系统上,有时候我们遇到so文件的crash仅仅能打log,可是非常多时候并不知道crash在什么地方,幸运的是crash后,一般能够产生一个.dmp文件. 我们能够依据这个文 ...

  7. Semantic UI中的验证控件的事件的使用

    1.Semantic UI中的验证控件,功能挺不错的,中文官网的文档写的都比较详细了,我再这里就不再进行重复了,主要是想说一下它的事件的使用方法,这个可能有部分朋友刚开始接触的时候不太了解 注意看这几 ...

  8. iOS坐标转换

    // 将像素point由point所在视图转换到目标视图view中,返回在目标视图view中的像素值 - (CGPoint)convertPoint:(CGPoint)point toView:(UI ...

  9. json(转)

    转自:http://www.cnblogs.com/mcgrady/archive/2013/06/08/3127781.html 阅读目录 JSON的两种结构 认识JSON字符串 在JS中如何使用J ...

  10. 场景切换特效Transition——Cocos2d-x学习历程(十二)

    Transition 场景切换 在游戏中通常会用到一些场景的切换,比如从加载界面切换到欢迎界面.游戏中的所有场景存放在一个栈中,有且只有一个场景可以处于激活状态.直接replaceScene(即不适用 ...