IOS基础之路

面向对象的思想在这就不赘述了。

OC的消息机制是通过[ ]来进行的,一般没有使用@property前缀的时候,参数是要通过->来访问的,但是通过@property修饰之后,编译器会自动添加set/get方法,此时通过点语法进行访问或者是赋值(具体是看语法行为,在左边还是在右边)。

在使用类创建对象之前,类会先进入内存中,创建对象后,每个对象都有个isa指针是指向类的,对象在底层中是只含有成员变量的,而方法是通过消息机制[  ]通过isa指针去找到类后,在类的方法列表中找方法的。

对象方法: - 

类方法: +

在设计类时,最好能将类方法与对象方法结合起来,降低冗余性。


self是一个指针,指向调用者当前方法的对象,指向方法的调用者。

在子类中,都有个superclass指针是指向父类的。

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

Animal* a = [Dog new];

a表面是Animal指针,但实际是指向Dog指针的

void feed(Animal* a)

{....}               此时既可以传入Dog指针,也可以指向Cat指针。

局限性:父类类型的指针是不能调用子类对象的特有方法的。


@private只能在当前类访问,子类中也不能,但可以用过set/get方法间接访问

@property 可以自动生成成员变量的setter和getter声明,用逗号可以连续声明,自动生成的setter和getter方法是 - (void) setXxx:(x* x) 和- (X* x)getXxx;

之所以在定义成员变量的时候是xxx时,但是在.m文件中访问的时候却是用_xxx是因为@synthesize已经对用户透明了,实际上已经自动实现了。


@property生成三件事  在Xcode4.4之后,@property独揽了@synthesize的功能

1、生成以下划线开头的成员变量(private类型)

2、set和get方法的声明

3、set和get方法的实现


声明中默认的是private变量,如果想改变类型,在前面加上@类型。

id指针,万能指针 id == NSObject* 


完整的创建一个可用对象:

1、分配存储空间 +alloc

2、初始化 -init  重写此方法可用初始化成员变量和其他属性。注意:必须要先self = [super init]先父类初始化。


分类:可以给某一个类扩充一些方法(不修改原来类的代码)

声明:@interface: 类名(分类名称)

           @end

实现同理

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

使用注意:

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

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

调用方法顺序:优先去分类中找,然后再去类中找,最后再去父类中找。

                  3、分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法不再能用。

                  分类的调用顺序可以再Xcode里调整,在Build Phases中的Compile Sources中


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

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

3、先加载父类,再加载子类(先调用父类的+load方法,再调用子类的+load方法)先初始化父类,再初始化子类(先调用父类的+initialize方法。在调用子类的+initialize方法)


- description方法

默认情况下是输出<类名:内存地址>

+ description

用来输出类而不是对象的,因为isa指针是指向对象所属的类的


SEL

在底层中,对象是没有方法的,是调用类的方法的,类中有方法列表

当调用 [p test2]时,会把test2包装成sel类型的数据,

                                根据sel数据找到对象的方法地址

                                根据方法地址调用对应的方法。

这个操作是有缓存的,第一次调用会遍历方法列表,之后就不会了。

SEL  S = @selector(test:);

SEL S2 = NSSelectorFromString(@selector(test));


每个方法都有个_cmd,代表着当前的方法

SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据。

去找对应的方法地址。找到方法地址就可以调用方法了。其实消息就是SEL。


内存管理

野指针:指向僵尸对象(不可用对象)的指针。

僵尸对象:对象被回收,不可用了。retainCount ==0;

谁创建,谁release alloc,new,(mutable)copy创建,必须用release和autorelease

dealloc,当一个对象要被回收的时候就会调用此方法。注意:一定要调用[super dealloc],而且要放在最后面调用。

给空指针发送消息是不会报错的。

指针清空 b = nil;


原则:1、想使用某个对象,就应该让计数器+1,(retain)

           2、不想使用(占用),计数器-1 (release)

           3、谁retain,谁release;

注意set方法:

这段代码在后面简称为set的if代码

if ( car != _car)   //这里的_car是当前对象的成员变量(也就是旧对象)

{

       [_car release];//传进来的值不是旧值,那么就将旧值先release

       _car = [car retain];//再赋新值

}

set方法中,如果重复赋值,就会存在僵尸对象,所以先利用if语句判断与之前的是否一样。情形一:重复赋值

情形二:换车

要在set方法中对原先的对象进行release[_car release];

内存管理代码规范:匿名对象不可取

1、只要调用alloc。必须有release(autorelease),如果对象没用alloc产生,则不要用release;

2、set方法的代码规范

      1、基础数据类型:直接赋值   _age = age;

      2、OC对象类型:利用上面的if方法

3、dealloc方法的代码规范

      1、一定要在最后加上[super deallc];

      2、对当前对象所有用的其他对象作一次release;


@property参数

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

  1、retain:release旧值,retain新值(适用于OC对象)==>set的if代码块

  2、assign:直接赋值(适用于非OC对象)

  3、copy:release旧值,copy新值

2、是否要生成set方法

  1、readwrite:同时生成setter和getter的声明和实现(默认)

  2、readonly:只生成getter方法的声明和实现

3、多线程管理

  1、nonatomic:性能高(一般用这个)

  2、atomic:性能低(默认)

4、setter和getter方法的名称

  1、setter:决定了set方法的名称,一定要有冒号;  (setter = xx:);

  2、getter:决定了get方法的名称;


time_t类型还是long类型


循环引用

@class xx;   告诉编译器,xx是一个类,循环引用时用@class很多

1、@class的作用:声明一个类;

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

  1、在.h文件中用@class来声明;

  2、在.m文件中用#import来导入所有东西

3、循环引用的解决方法

  1、一端用retain;

  2、一端用assign;


@autorelease的实质是在代码块结束的时候对所有在自动释放吃里的对象做一次release,并非是dealloc

,只是将将繁琐的代码简化了!

注意点:

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

2、较小的使用autorelease

在创建类方法时,尽量用self。


ARC机制(这是oc编译器的特性,不是像java的垃圾回收!)

ARC的判断准则:只要没有了强指针指向对象,那么此对象就会被释放,并且将所连带若指针也销毁,且指针清空;

指针分两种:

1、强指针:默认情况下,所有指针都是强指针(strong)默认;

2、弱指针:如果只有弱指针指向对象,那么此对象就会被释放,指针也为空。(weak)场合:循环引用 

                    错误写法:....weak Person* p = [[Person alloc] init];

@property的参数在ARC中不能用retain和release;

如果保证人在狗就在,那么使用强指针;

如果保证人在狗不一定在,那么使用弱指针;

ARC的特点:

1、不允许使用retain,release,retainCount;

2、允许重写dealloc,但不允许使用[super dealloc];

@property参数

1、strong:相当于原来的retain(适用于oc对象)

2、weak:相当于原来的assign(适用于oc对象)

3、assign:适用于非oc对象类型


如果项目中某些文件不需要ARC机制,那么在Targets中的Build Phases的Compile Sources的Compiler flags里写 -fno-objc-arc

在ARC机制中,循环引用:一端用strong,一端用weak;


Block数据类型

Block封装了一段代码,可以再任何时候执行。

int (^sumblock) (int,int) = ^(int a, int b)

{..........................................return a + b;};

sumblock(5,4);

block内部不能修改外面的局部变量,可以修改全局变量。

在局部变量前加上  __(两个下划线)block就可以在内部访问了

block要掌握的东西  (开发中常常用到block)

1、如果定义block变量

int (^sumblock) (int ,int);

void (^myblock) ();

2、block封装代码

^ (int a,int b)

{

   retuan a + b;

}

3、block内部访问外面的变量;

4、利用typedef定义block变量

typedef int (^mybloc(int,int));


@protocal协议

用途:

1、可以用来声明一大堆方法(不能声明成员变量),没有实现;

2、只要某个类遵守这个协议,就相当于拥有这个协议中的所有方法的声明;

3、只要父类遵守了某个协议,相当于子类也遵守了。

类名(协议)

委托代理协议



我是分割线,萨瓦迪卡!

—————————————————————————————————————————————————————————————————————————————


Foundation框架

常用数据类型:结构体

                         枚举

                         类

结构体:NSRange:范围:.location   .length       NSMakeRange

               NSpoint/CGPoint:x,y

               NSSize/CGSize:weight,height

               NSRect:矩形,Point和Size

NSNotFound = - 1;

零点:CGPointZero;


NSString

C字符串  UTF8String

URL:资源路径

协议头://路径

NSURL是万能的,能代表一切资源路径


OC数组只能存放OC对象,不能放基本类型

OC数组不能存放nil值

NSFileMa=nger是单例类,整个程序只有这一个类。


[array enumerateObjectsUsingBlock:    //这个方法的本质 第三个参数*stop是一个代码设计逻辑,亮点。通过指针利用地址传值
     // 每遍历到一个元素,就会调用一次block
     // 并且当前元素和索引位置当做参数传给block
     ^(id obj, NSUInteger idx, BOOL *stop)
     {
         NSLog(@"%ld - %@", idx, obj);
        
        
         if (idx == 0)
         {
             // 停止遍历
             *stop = YES;
         }
        
     }];

for (int i = 0; i<array.count; i++)
    //    {
    //        // 用来标记是否需要停止遍历
    //        BOOL isStop = NO;
    //
    //        // 取出元素
    //        id obj = array[i];
            
            myblock(obj, i, &isStop);
              
              
            if (isStop)

             {
            break;
             }

 }


Xcode小技巧

通过#pragma mark  -  xxx类似于标签,代码量很大时可以更有效率





点语法的本质是方法调用,编译器会自动展开成相应的方法。get/set方法。区分是看在左边还是在右边,看行为本质是什么。

@private:只能在当前类访问,子类也不能,但可以通过方法,set/get;

@property:可以自动生成成员变量的set/get方法,用逗号可以连续声明;

@synthesize 自动实现 在.m文件中成员变量前面自动加上了下划线和get/set方法


@property 生成三件事    Xcode4.4之后 @property独揽了@synthesize的功能

顺序:1、set/get方法的声明

           2、set/get方法的实现

           3、生成以下划线开头的成员变量(private类型)


id指针 万能指针

id == NSObject*

完整地创建一个可用对象

1、分配存储空间 +alloc

2、初始化    -init   重写此方法可用初始化成员变量和其他属性。注意:必须要先self = [super init]先父类初始化。


分类:可以给某一个类扩充一些方法(不修改原来类的代码)

声明:@interface 类名(分类的名称)

           @end

实现同理

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

使用注意:

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

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

调用顺序:优先去分类中找,找不到然后去类中找,最后再去父类中找。

3、分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法不能再用。

调用顺序:看Xcode的设置顺序,在Build Phases中的Compile Sources中


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

2、当第一次使用某个类的时候。就会调用当前类


集合
1.NSArray\NSMutableArray
 有序
 快速创建(不可变):@[obj1, obj2, obj3]
 快速访问元素:数组名[i]
 
2.NSSet\NSMutableSet
 无序
 

3.NSDictionary\NSMutableDictionary
 无序
 快速创建(不可变):@{key1 : value1,  key2 : value2} (NSDictionary)
 快速访问元素:字典名[key]

 添加键值对用set,同名键值对即是覆盖。


[NSDate date]获取的是格林时间。

NSDateFormatter *f = [[NSDateFormatter alloc] init];  日期格式类

f.dataFormat = @"......."

y年M月d日 H时(24)h(12)m分 s秒



游戏时钟QuartzCore/QuartzCore.h

CADisplayLink 游戏时钟,刷新频率 约等于FPS = 60

NSRunloop 应用程序循环


代理用weak是因为循环引用,UI控件用weak是因为view的subviews数组对控件已经是强引用了。
纯代码开发中,UI控件之所以是weak因为控件是addsubview了,view对控件进行了强引用,而@property是weak自然是明白了


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值