object-c 一句话心得

1. 在成员变量的声明时候,不要加上@public,不然成员变量的值就变得可以在类方法之外也能随便改变。正确的方法是通过set方法(写入)和get方法(读取)来操作成员变量。

set,get格式:

int  _sex

- (void)setSex : (int)sex;

- (int)sex;


2.成员变量命名规范:一定要以下划线_ 开头.有利于与局部变量区分来


3.经典错误: unrecognized selector sent to instance   给对象发送了一个无法识别的消息 。 【p run】 要是run没有定义实现 就会出现。

这是OC的弱语法。在编译链接的时候 不会报错误 只会提出警告。但是在程序运行时就会出现。这是因为OC的动态实现,运行时才发消息,检测方法是否有实现。


4.类方法不能访问实例变量(成员变量),对象才可以。 类在内存中是一块空间,只存有方法列表。 对象在内存是另一块空间,存有实例变量和指向类内存空间实例方法列表的isa指针。


4.类方法执行效率比对象方法高,不依赖于对象。当类方法内部不需要使用成员变量的话,就尽量使用类方法。


5.谁调用了当前方法,self就代表谁。

利用self->成员变量名 访问当前对象内部的成员变量


self出现在对象方法中,self就代表当前对象。

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

利用self调用类方法[self 方法名]  self代表类


2.继承注意事项:

1.父类必须声明在子类前面。

2.不允许子类和父类拥有相同名称的成员变量。

3.调用某个方法时,优先寻找子类是否有满足调用需求的方法,找不到再去父类找,一层层往上找。   成员变量也一样,就近原则。

4.对象调用方法时,会通过自己指向类的isa指针,去类中寻找方法如果找不到就去父类里面找,,子类中有superclass指针指向其父类。

5.A类拥有B类的属性方法的时候,可以继承,但是前提要逻辑对。比如A类为成绩,B类为学生。这是B类就不能去继承A类,因为逻辑不正确。

这时就考虑使用组合。


组合:

在学生类的成员变量里面,实例化一个成绩对象。

@interaface Student : NSObject

{

Scode *scode;

}


继承的组合使用场合简单判断: 

XX是XXX   继承 学生是人

XX拥有XXX      组合 学生拥有成绩


super:调用父类的方法。至于是调用类方法还是对象方法 看它所在的环境   

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

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

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

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



多态: 多种形态。

a.没有继承就没有多态

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

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

用一个父类指针变量就可以指向多个子类对象

 多态的好处:

当一个方法 在猫上面跟狗上面都是一样的,就直接定义一个动物类指针 然后传入猫狗参数来调用



局限性:父类类型的变量不能直接调用子类特有的方法。 必须强制把子类对象转换为父类类型才可以了


NSString:

@interface Person : NSObject
{
    //char *_name;
    NSString *_name;
}
@end


int main()
{
    /*
    // 最简单的创建字符串的方式
    NSString *str = @"itcast";
    
    char *name = "itcast";
    
    
    NSLog(@"我在%@上课", str);
    //NSLog(@"%s", name);
    */
    
    int age = 15;
    int no = 5;
    NSString *name = @"哈哈jack";
    // length方法算的是字数
    int size = [name length];
    
    NSLog(@"%d", size);
    
    // 创建OC字符串的另一种方式
    NSString *newStr = [NSString stringWithFormat:@"My age is %d and no is %d and name is %@", age, no, name];
    
    
    NSLog(@"---- %ld", [newStr length]);
    
    return 0;
}



类的分文件使用:

定义一个类分两个文件: .h声明文件    .m实现文件

.h:成员变量,方法的声明

.m: 方法的实现


如果想使用某个类,只需要#import类的  .h 文件即可以。

注释标记 加 - 就会多一条横线 用来分组

#pragma mark


C语言中,非零就是“1” 零就是“0” ,与C语言不同,OC中,1就是“1” 也可以是YES 0就是“0”也可以是NO


点语法:本质是把语句转换成 set 和 get 方法

 Person *p = [Person new];

 p.age = 10;

需要注意的是:这里的点语法不是去访问类的成员变量,而是编译器会自动帮我们把p.age = 10这行代码转换成[p setAge: 10]

同样的:

int a = p.age;  转换为 [p age];

点语法使用注意:

注意不要在set和get方法定义里面使用self.age; 不然会进入死循环。

在声明和定义里面还是要自己写set和get方法。


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

@protected   能在当前类和 子类 的对象方法中直接访问 (@interface 默认是protected)


继承是父类的成员变量方法 子类都继承了,但是关键是能不能访问。


id类型: 是一个能指向 任何 oc对象的指针。 id d = [Person new]注意不要加上*


构造方法:这个变量属于谁,你就在谁那里初始化。


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


description方法:

默认情况下,利用NSLog和@%输出对象信息时,结果是:《类名 : 内存地址》

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

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

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


引用计数器占 四个 字节


当使用alloc new copy创建新对象的时候,新对象的引用计数器默认就是1 当计数器值为0的时候  对象占用的内存才会被回收

retain              引用计数+1   用到的时候就要加1

release            引用计数-1

retainCount     查询引用计数


当对象引用计数器值为0 时 对象会被销毁,其所占用的内存会被系统回收。当对象被销毁时,系统会自动向对象发送一条dealloc消息,我们一般会重写dealloc方法来释放一些资源。

对于dealloc,最后都要加上 [super dealloc]


xcode7 取消arc:

打开你的工程,点击目录的工程文件,最顶端蓝色的,然后双击project下你的工程,还是蓝色那项,然后build Settings,然后往下拉,在Apple LLVM 5.0 - Language - Objective C 里有一个选项,Objective-C Automatic Reference Counting 选择NO,就可以了。

project -> 

build Settings -> 

Apple LLVM 5.0 - Language - Objective C ->

Objective-C Automatic Reference Counting 选择no


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

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

空指针:没有指向任何东西的执政

当你想用某个对象的时候 你就需要调用该对象的retain方法,使其计数器加1 ,当你不想用的时候你就要release,使其计数器减1,当对象的计数器为0的时候,就会调用dealloc方法,这时如果 对象里面拥有别的对象,就要在这里释放掉 ,在dealloc方法里面,最后要加上[super dealloc],然后记得要把对象指针设为nil   p = nil。


原则:

1.谁retain,谁release。

 你想使用(占用)某个对象,就应该让对象的计数器+1(调用一次对象的retain方法)

你不想再使用(占用),就应该让对象的计数器-1(调用对象的release方法)

2.谁alloc, 谁release。


内存管理代码规范:

 1.只要调用了alloc,必须有release

 2.set方法的代码规范

 1》基本类型数据类型:直接复制

 - (void)setAge:(int)age

{

  _age = age;

}

 2》oc对象类型

 - (void)setCar:(Car *)car

{

  //1.先判断是不是新传入的对象

  if( car != _car)

  {

  //2.对旧对象做一次release

     [ _car release];

 //3.对新对象做一次retain

   _car = [car retain];

  }

}


3.delloc方法的代码规范

1》一定要[super dealloc] 而且放到最后面

2》对self(当前)所拥有的其他对象做一次release

 - (void)dealloc

{

 [ _car release];

 [ super dealloc];

}


当get方法的返回值为bool类型,就要写成下面的格式( 把方法名修改成is+变量名 首字母大写)

@property  (getter = isRich) bool rich



1.set方法内存管理相关的参数
 * retain : release旧值,retain新值(适用于OC对象类型)
 * assign : 直接赋值(默认,适用于非OC对象类型)
 * copy   : release旧值,copy新值
 
 2.是否要生成set方法
 * readwrite : 同时生成setter和getter的声明、实现(默认)
 * readonly  : 只会生成getter的声明、实现
 
 3.多线程管理
 * nonatomic : 性能高 (一般就用这个)
 * atomic    : 性能低(默认)
 
 4.setter和getter方法的名称
 * setter : 决定了set方法的名称,一定要有个冒号 :
 * getter : 决定了get方法的名称(一般用在BOOL类型)
 */


开发中引用一个类的规范

 1.在" person.h "文件中 使用@class card   来包含card类

 2.然后在 main.m文件中才用#import来包含头文件card.h


两端循环引用解决方案 person card互相引用 则 在@property 参数中

1. 一端使用retain

2.一端使用assign


autorelease 其实就是相当于在最后的时候 对池的对象都做一次 release


内存管理总结:

一、计数器的基本操作
1> retain : +1
2> release :-1
3> retainCount : 获得计数器

二、set方法的内存管理
1> set方法的实现
- (void)setCar:(Car *)car
{
    if ( _car != car )
    {
        [_car release];
        _car = [car retain];
    }
}

2> dealloc方法的实现(不要直接调用dealloc)
- (void)dealloc
{
    [_car release];
    [super dealloc];
}

三、@property参数
1> OC对象类型
@property (nonatomic, retain) 类名 *属性名;
@property (nonatomic, retain) Car *car;
@property (nonatomic, retain) id car;

// 被retain过的属性,必须在dealloc方法中release属性
- (void)dealloc
{
    [_car release];
    [super dealloc];
}

2> 非OC对象类型(int\float\enum\struct)
@property (nonatomic, assign) 类型名称 属性名;
@property (nonatomic, assign) int age;

四、autorelease
1.系统自带的方法中,如果不包含alloc、new、copy,那么这些方法返回的对象都是已经autorelease过的
[NSString stringWithFormat:....];
[NSDate date];

2.开发中经常写一些类方法快速创建一个autorelease的对象
* 创建对象的时候不要直接使用类名,用self

-------------
ARC

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

1.ARC特点

 1> 不允许调用release、retain、retainCount
 2> 允许重写dealloc,但是不允许调用[super dealloc]
 3> @property的参数
  * strong :成员变量是强指针(适用于OC对象类型)
  * weak :成员变量是弱指针(适用于OC对象类型)
  * assign : 适用于非OC对象类型
 4> 以前的retain改为用strong
 
 指针分2种:
 1> 强指针:默认情况下,所有的指针都是强指针 __strong
 2> 弱指针:__weak

把没有arc的旧项目转换为新的有arc的项目方法:

点击xcode菜单 edit-》convert-》to object-c ARC


ARC循环引用,一端使用week,一端使用strong。

比如 人拥有一只狗。这时候 人的狗是dog  狗的主人是person

就会循环引用 导致释放不了 这是就需要 person和dog

在pproperty的时候 一方为strong 一方为week。


非ARC就一端用retain 一端用assign


-------------------------------

BLOCK

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;
 };


--------------

Foundation

/*
 集合
 1.NSArray\NSMutableArray
 * 有序
 * 快速创建(不可变):@[obj1, obj2, obj3]
 * 快速访问元素:数组名[i]
 
 2.NSSet\NSMutableSet
 * 无序
 
 3.NSDictionary\NSMutableDictionary
 * 无序
 * 快速创建(不可变):@{key1 : value1,  key2 : value2}
 * 快速访问元素:字典名[key]
 */

#import <Foundation/Foundation.h>

int main()
{
    NSArray *persons = @[
    @{@"name" : @"jack", @"qq" : @"432423423", @"books": @[@"5分钟突破iOS编程", @"5分钟突破android编程"]},
    @{@"name" : @"rose", @"qq" : @"767567"},
    @{@"name" : @"jim", @"qq" : @"423423"},
    @{@"name" : @"jake", @"qq" : @"123123213"}
    ];
    
    //
    // NSDictionary *jim = persons[2];
    
    
    //
    NSString *bookName = persons[0][@"books"][1];
    NSLog(@"%@", bookName);

440106199509220046 19950922

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值