OC基础

一、对象方法

 1> 减号 - 开头

 2> 只能由对象来调用

 3> 对象方法中能访问当前对象的成员变量(实例变量)

 

 类方法

 1> 加号 + 开头

 2> 只能由类(名)来调用

 3> 类方法中不能访问成员变量(实例变量)

 

 

 类方法的好处和使用场合

 1> 不依赖于对象,执行效率高

 2> 能用类方法,尽量用类方法

 3> 场合:当方法内部不需要使用到成员变量时,就可以改为类方法

 

 可以允许类方法和对象方法同名

二、self的用途:

 1> 谁调用了当前方法,self就代表谁

 * self出现在对象方法中,self就代表对象

 * self出现在类方法中,self就代表类

 

 2> 在对象方法利用"self->成员变量名"访问当前对象内部的成员变量

 

 2> [self 方法名]可以调用其他对象方法\类方法

三、1.继承的使用场合

 1> 当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中

 2> A类完全拥有B类中的部分属性和方法时,可以考虑让B类继承A

 继承:xx xxx

 组合:xxx 拥有 xxx

四、super的作用

 1.直接调用父类中的某个方法

 2.super处在对象方法中,那么就会调用父类的对象方法

   super处在类方法中,那么就会调用父类的类方法

 

 3.使用场合:子类重写父类的方法时想保留父类的一些行为

五、 多态

 1.没有继承就没有多态

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

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

 4.局限性:

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

六、NSString

    创建OC字符串的另一种方式

    NSString *newStr = [NSString stringWithFormat:@"My age is %d and no is %d and name is %@", age, no, name];

    最简单的创建字符串的方式

    NSString *str = @"it cast";

    length方法算的是字数

    int size = [name length];


七、 点语法的本质还是方法调用


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

 @private : 只能在当前类的对象方法中直接访问(@implementation中默认是@private

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

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

 

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

九、@property 和@synthesize

OC基础_第1张图片
OC基础_第2张图片

OC基础_第3张图片

OC基础_第4张图片





十、

构造方法:用来初始化对象的方法,是个对象方法,-开头

 重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值


 重写构造方法的注意点

1.先调用父类的构造方法([super init]

2.再进行子类内部成员变量的初始化


// 重写-init方法

//- (id)init

//{

//    // 1.一定要调用回superinit方法:初始化父类中声明的一些成员变量和其他属性

//    self = [super init]; // 当前对象 self

//    

//    

//    // 2.如果对象初始化成功,才有必要进行接下来的初始化

//    if (self != nil)

//    { // 初始化成功

//        _age = 10;

//    }

//    

//    // 3.返回一个已经初始化完毕的对象

//    return self;

//}


- (id)init

{

    if ( self = [super init] )

    { // 初始化成功

        _age = 10;

    }

    

    // 3.返回一个已经初始化完毕的对象

    return self;

}

十一、

分类的作用:在不改变原来类内容的基础上,可以为类增加一些方法

 

 使用注意:

 1.分类只能增加方法,不能增加成员变量

 2.分类方法实现中可以访问原来类中声明的成员变量

 3.分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法没法再使用

 4.方法调用的优先级:分类(最后参与编译的分类优先) -->原来类  --> 父类

十二、

  类的本质

 1.当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法。只会调用一次。

 

 2.当第一次使用某个类时,就会调用当前类的+initialize方法

 

 3.先加载父类,再加载子类(先调用父类的+load方法,再调用子类的+load方法)

  先初始化父类,再初始化子类(先调用父类的+initialize方法,再调用子类的+initialize方法)



   获取类对象的两种方式:
 1.Class c  = [Person class]; //类方法

 2.Person *p = [[Person alloc] init];
    Class c2 = [p class];//对象方法

   类对象调用类方法
   Class c  = [Person class];
   Person *p2 = [c new];

十三、   

     description方法

  1  // 默认情况下,利用NSLog%@输出对象时,结果是:<类名:内存地址>

    // 1.会调用对象p-description方法

    // 2.拿到-description方法的返回值(NSString *)显示到屏幕上

    // 3.-description方法默认返回的是类名+内存地址


  2  // 1.会调用类的+description方法

    // 2.拿到+description方法的返回值(NSString *)显示到屏幕上


十四、 SEL用法 

OC基础_第5张图片

eg:  Person *p = [[Person alloc] init];

    

      [p test2];

    

//    NSString *name = @"test2";

//    

//    SEL s = NSSelectorFromString(name);

//    

//    [p performSelector:s];

    

    

    // 间接调用test2方法

    //[p performSelector:@selector(test2)];

    

    //[p test3:@"123"];

    

    

//    SEL s = @selector(test3:);

//    

//    [p performSelector:s withObject:@"456"];

    

    //[p test2];

    

    // 1.test2包装成SEL类型的数据

    // 2.根据SEL数据找到对应的方法地址

    // 3.根据方法地址调用对应的方法


十五、1.方法的基本使用

 1> retain :计数器+1,会返回对象本身

 2> release :计数器-1,没有返回值

 3> retainCount :获取当前的计数器

 4> dealloc

  * 当一个对象要被回收的时候,就会调用

  * 一定要调用[super dealloc],这句调用要放在最后面

 

 2.概念

 1> 僵尸对象:所占用内存已经被回收的对象,僵尸对象不能再使用

 2> 野指针:指向僵尸对象(不可用内存)的指针,给野指针发送消息会报错(EXC_BAD_ACCESS

 3> 空指针:没有指向任何东西的指针(存储的东西是nilNULL0),给空指针发送消息不会报错


 1.你想使用(占用)某个对象,就应该让对象的计数器+1(让对象做一次retain操作)

 2.你不想再使用(占用)某个对象,就应该让对象的计数器-1(让对象做一次release

 

 3.retain,谁release

 

 4.alloc,谁release


十六、@property参数

 1.set方法内存管理相关的参数

 * retain : release旧值,retain新值(适用于OC对象类型)

 * assign :直接赋值(默认,适用于非OC对象类型)

 * copy   : release旧值,copy新值

 

 2.是否要生成set方法

 * readwrite : 同时生成settergetter的声明、实现(默认)

 * readonly  : 只会生成getter的声明、实现

 

 3.多线程管理

 * nonatomic : 性能高 (一般就用这个)

 * atomic    : 性能低(默认)

 

 4.settergetter方法的名称

 * setter : 决定了set方法的名称,一定要有个冒号 :

 * getter : 决定了get方法的名称(一般用在BOOL类型)

十七、循环retain

 1.@class的作用:仅仅告诉编译器,某个名称是一个类

 @class Person; //仅仅告诉编译器,Person是一个类

 

 2.开发中引用一个类的规范

 1> .h文件中用@class来声明类

 2>.m文件中用#import来包含类的所有东西

 

 3.两端循环引用解决方案

 1> 一端用retain

 2> 一端用assign


十八、autorelease

 1.autorelease的基本用法

 1>会将对象放到一个自动释放池中

 2>当自动释放池被销毁时,会对池子里面的所有对象做一次release操作

 3>会返回对象本身

 4> 调用完autorelease方法后,对象的计数器不变

 

 2.autorelease的好处

 1>不用再关心对象释放的时间

 2> 不用再关心什么时候调用release

 

 3.autorelease的使用注意

 1> 占用内存较大的对象不要随便使用autorelease

 2>占用内存较小的对象使用autorelease,没有太大影响

 

 

 4.错误写法

 1> alloc之后调用了autorelease,又调用release

 @autoreleasepool

 {

    // 1

    Person *p = [[[Person alloc] init] autorelease];

 

    // 0

    [p release];

 }

 

 2> 连续调用多次autorelease

 @autoreleasepool

 {

    Person *p = [[[[Person alloc] init] autorelease] autorelease];

 }

 

 5.自动释放池

 1>iOS程序运行过程中,会创建无数个池子。这些池子都是以栈结构存在(先进后出)

 2>当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池

 

 

 6.自动释放池的创建方式

 1> iOS 5.0

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

 

 [pool release]; // [pool drain];

 

 

 2> iOS 5.0 开始

 @autoreleasepool

 {

    

 }


 3.系统自带的方法里面没有包含allocnewcopy,说明返回的对象都是autorelease

 

 4.开发中经常会提供一些类方法,快速创建一个已经autorelease过的对象

 1>创建对象时不要直接用类名,一般用self

 + (id)person

 {

    return [[[self alloc] init] autorelease];

 }

十九、

ARC的判断准则:只要没有强指针指向对象,就会释放对象 

 1.ARC特点

 1> 不允许调用releaseretainretainCount

 2> 允许重写dealloc,但是不允许调用[super dealloc]

 3> @property的参数

  * strong:成员变量是强指针(适用于OC对象类型)

  * weak:成员变量是弱指针(适用于OC对象类型)

  * assign : 适用于非OC对象类型

 4> 以前的retain改为用strong

 

 指针分2种:

 1>强指针:默认情况下,所有的指针都是强指针 __strong

 2> 弱指针:__weak


当两端循环引用的时候,解决方案:

 1> ARC

 1端用strong,另1端用weak

 

 2> ARC

 1端用retain,另1端用assign



二十、block要掌握的东西

 1> 如何定义block变量

 int (^sumBlock)(int, int);

 void (^myBlock)();

 

 2> 如何利用block封装代码

 ^(int a, int b) {

    return a - b;

 };

 

 ^() {

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

 };

 

 ^ {

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

 };

 

 3> block访问外面变量

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

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

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

 

 4> 利用typedef定义block类型

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

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

 MyBlock block;

 MyBlock b1, b2;

 

 b1 = ^(int a, int b) {

    return a - b;

 };

 

 MyBlock b3 = ^(int a, int b) {

    return a - b;

 };

二十一、 协议

1.协议的定义

 @protocol 协议名称

  // 方法声明列表....

 @end

 

 

 2.如何遵守协议

 1> 类遵守协议

 @interface 类名 : 父类名 <协议名称1, 协议名称2>

 

 @end

 

 2> 协议遵守协议

 @protocol 协议名称 <其他协议名称1, 其他协议名称2>

 

 @end

 

 3.协议中方法声明的关键字

 1> @required (默认)

   要求实现,如果没有实现,会发出警告

 

 2> @optional

   不要求实现,怎样不会有警告

 

 4.定义一个变量的时候,限制这个变量保存的对象遵守某个协议

 类名<协议名称> *变量名;

 id<协议名称> 变量名;

 NSObject *obj;

 id obj2;

 

 如果没有遵守对应的协议,编译器会警告

 

 5.@property中声明的属性也可用做一个遵守协议的限制

 @property (nonatomic, strong) 类名<协议名称> *属性名;

 @property (nonatomic, strong) id<协议名称> 属性名;


 @property (nonatomic, strong) Dog *dog;

 @property (nonatomic, strong) id dog2;

 

 6.协议可用定义在单独.h文件中,也可用定义在某个类中

 1> 如果这个协议只用在某个类中,应该把协议定义在该类中

 

 2> 如果这个协议用在很多类中,就应该定义在单独文件中

 

 7.分类可用定义在单独.h.m文件中,也可用定义在原来类中

 1> 一般情况下,都是定义在单独文件

 2> 定义在原来类中的分类,只要求能看懂语法



你可能感兴趣的:(objective-c,基础)