OC分类、类方法、实例方法、OC 基础知识及常用的for/in方法

在OC中有个分类的功能,C++中没有,分类可以很好地在类中添加新的方法,而不是用继承来实现。

分类的固定框架:

类名+增加函数名.m,与类实现函数放在同一个目录下面,在分类函数中@interface 类名(新增函数名)

OC中分类是如何实现的?

分类的使用是通过Objective-C的动态绑定实现,通过分类能够实现比继承更好的效果,通过category不能添加新的实例变量

OC 中的动态类型检查和静态类型检查

静态类型检查是指在程序编译期间,编译器会会检查该类型是否有对应的方法。

动态类型检查是指指使用好几种不同的方式指向同一个类型。

sample:

    NSArray *array=[NSMutableArrayarray];

    [array addObject:@"hello"];

上面这段代码在运行时是正常的,但在编译期间会有warning,因为NSArray没有addObject函数

NSMutableArray *mutableArray=[NSMutableArrayarray];

    NSArray *array=[NSArrayarray];

    mutableArray=array;

    [mutableArray addObject:@"hello"];

    上面这段代码编译会有warning,  但在执行时出错

在XCode中可以设置xcode ,将警告当做错误对待


类方法前面有+,实例方法前面有-

类方法和实例方法的区别在于,类方法不能使用实例变量。

使用类方法主要原因有:

1.类方法的使用不依赖于实例化一个对象,也就是说如果一个功能的实现不需要实例化对象,就可以用类方法来实现。

2.类方法可以隐藏单例,将类方法和单例结合,可以在应用程序的任何地方访问静态实例,而无需使用指向对象的指针或保存他的实例变量。

3.类方法和内存管理相关,分配一个NSArray,可以【NSArray alloc】init,也可以【NSArray array】,但是前者必须释放,而后者返回一个随时准备好自动释放的数组对象,并不需要你进行release操作


OC中常用的for/in 方法实现

int main(int argc, const char * argv[])

{

    NSArray *colors=[NSArrayarrayWithObjects:@"hello",@"richard",@"yang",nil];

    for(NSString *strin colors)

    {

        NSLog(@"the val is %s",[strUTF8String]);

    }

        return 0;

}

第一、关于super

向super发送信息时,实际上是请求Objectiv-c向该类的超类发送消息,如果超类没有定义该消息,objective-c将按照通常的方式在继承链中继续查找对应的消息

第二、关于继承的实例变量

创建一个新类时,其对象首先从其自身的超类继承实例变量,然后再添加自己的实例变量,由于类的基类是NSObject,所以每个类最前面都是isa指针,代表NSObject的实例变量。

第三、lazy evaluation(惰性求值)

在init函数中没有进行创建,当在使用时先判断是否为空,如果为空则创建,这样会节省内存,提高效率

第四、关于属性

利用属性可以减少需要编写的代码,使用@property预编译指令可以通知编译器,该变量具有的特征:可读、可写、对象的内存管理、并发性,此外编译器应该自动生成set方法和get方法。

在xcode4.2版本的编译器上,@property声明的变量,前面加下划线的变量就是私有变量,在_init函数中直接操作该变量,在dealloc函数中一定要release,如果该变量在init函数中没有初始化,也应该release,因为对于nil变量执行release是不会报错的

第五、关于循环引用的问题

A引用B,B引用A,在A的dealloc函数中先要释放B的对象才能【super dealloc】,在B的dealloc函数中先要释放A的对象才能【super dealloc】,陷入死循环。

解除死循环的方法,在B中定义A的变量时为assign

sample code:

- (void)setC:(C *)c
{
    if (_c != c) {
        [_c release];
        _c = [c retain];
    }
}

- (void)setB:(B *)b
{
    if (_b != b) {
        [_b release];
        _b = [b retain];
    }
}

B *b = [[B alloc] init]; // 1
        C *c = [[C alloc] init]; // 1
        [b setC:c];  // c : 2
        NSLog(@"c retaincount is %lu",[c retainCount]);
        [c setB:b];
        NSLog(@"b retaincount is %lu",[b retainCount]);
        [c release];
        [b release];
        NSLog(@"c retaincount is %lu",[c retainCount]);
        NSLog(@"b retaincount is %lu",[b retainCount]);
result:

RetainCycle[1102:303] c retaincount is 2

2013-12-28 21:49:36.936 RetainCycle[1102:303] b retaincount is 2

2013-12-28 21:49:36.937 RetainCycle[1102:303] c retaincount is 1

2013-12-28 21:49:36.937 RetainCycle[1102:303] b retaincount is 1

往下执行:

[c release];

[b release];

就会报错




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值