IOS开发学习笔记(二十二)——ObjectC语言难以理解的概念汇总

来源:互联网 发布:mac 链接阿里云服务器 编辑:程序博客网 时间:2024/04/28 01:48

这篇文章将会对ObjectC语言中比较难理解的概念进行汇总,帮助我们更好的进行iOS开发。


方法&成员变量&属性

我们首先看一个很简单的方法代码:

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;


对于我这种用了多年C/C++和Java的程序员来说,实在比较难以理解,但是换个角度可以这样理解:

  1. 方法名称你可以认为是dequeueReusableCellWithIdentifier_forIndexPath;
  2. 参数有两个,第一个是NSString *类型,名字叫identifier;第二个是NSIndexPath *类型,名字叫indexPath;
  3. 最顶头的减号("-")标识是object方法,如果是加号("+")标识是静态(static)方法;
  4. 属性通过@private定义,并且需要你自己去显式通过实现方法来存取,或者.h文件中指定@property,.m文件中指定@synthesize来使得可以通过self.propertyName访问;
  5. 可以指定readonly指示符指示仅生成get方法;
  6. 注意对于静态方法(类方法)可以使用self或者super关键字指定使用自己还是父类的静态方法;

属性

对于属性中可能使用到的几个关键字我们这样理解:

  1. nonatomic关键字说明这个是非原子操作的,所以可能是非线程安全的;
  2. strong和weak关键字在所指定的属性是对象类型时使用。strong表示保持这个对象的指针所指向的内存,一直到使用结束;weak表示如果没有人再使用这个指针,那么就设置为nil;官方的解释是这样滴:
    strong is the default. An object remains “alive” as long as there is a strong pointer to it.
    weak specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.
    另外还有一个比喻:
    我们的属性可以认为是一条狗,他总是想逃跑;strong可以认为是狗链子,我们可以用多条链子拴住这条狗,只要有一条还抓在我们手里,狗就跑不了;而weak是一个看着狗的孩子,当链子在我们手中的时候,孩子可以看住狗,但是当链子不在我们手中时,狗就可以跑掉,尽管孩子在看着狗。
    .h
    @interface ViewController : UIViewController@property (nonatomic, strong) MyType *obj1;@property (nonatomic, weak) MyType *obj2;@end
    注意obj2是strong还是weak对程序运行结果的影响。
    .m
    - (void)viewDidLoad{    [super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.    obj1 = [[MyType alloc] init];    obj2 = obj1;        obj1 = nil;    NSLog(@"obj2 = %@", obj2);}
    注意weak是在iOS5以后引入的,所以如果你的代码需要在iOS4上面运行,你只能使用strong。
  3. 上面讲得实际上就是引用计数的概念,strong类型的对象会被加上引用计数,当最后一个对象不再保留引用计数的时候,strong的对象就会被自动释放,所以这个时间点相对垃圾回收机制来说是可预期的;
  4. 局部变量由于在方法执行结束后超出其作用于,所以会被自动清除引用计数;
  5. 对于非ARC的程序,weak对应的关键字是unretain,strong对应的是retain关键字;另外还有一个关键字unsafe_unretain这个会造成野指针,不推荐使用,就不赘述了;
  6. 所有的属性,在你没有设置默认的setter的时候,初始化的值都是0;
  7. 可以使用if (obj)判断对象是否是nil,但一般情况下你无须这样去做。对一个nil的对象做一个操作(例如调用一个方法)将不会真正去执行这个方法,如果这个方法是有返回值的,一般都会返回0;但是如果这个方法是返回一个C类型的结构值的,那么你需要自己去事先检查这个对象是否是nil,因为无法保证返回的结构中的成员变量是有效的还是无效的,可能是一堆垃圾数据;



对于如何使用方法/成员变量/属性,建议采用如下规则:
  1. 所有的实例变量都声明为:@private;
  2. 所有属性都是用@property定义,并在方法中采用self.property或者super.property的方式引用;
  3. .m文件中使用@synthesize使得编译器将setter和getter设置为与property同名的方法;
  4. 注意有这样的方法,可以强制你必须在代码中使用self.property的方式使用属性,在.m文件的interface段内这样写:
    @interface MyViewController ()@property int myPriveteProperty;@end

    这样你在方法中必须使用self.myPrivateProperty这样的方式来引用成员变量。
  5. 注意在对象使用前最好检测是否是nil,因为对于object.property的使用形式,如果object本身是nil,并且property本身是一个CType的一个结构类型变量,那么property本身的值是未知的,可能会导致不可预知的错误;
  6. 对于需要打印输出的对象,可以重写-(NSString *)description方法(类似于java中的toString),并且可以在NSLog()中使用%@输出;


变量类型

对于变量类型有几个需要注意的地方:

  1. Java中我们是可以定义一个String类型的变量(或者任意一个对象类型的变量),但在ObjectC中我们的对象必须使用指针类型定义:NSString *str;
  2. id类型返回任意一个对象类型的变量,类似于Object。但注意:返回的仍然是一个指针,类似于NSString *;
  3. 事件响应方法:IBAction返回值类似于void;
  4. 注意BOOL类型的变量是YES/NO,不再是TRUE/FALSE;


访问控制符

访问控制符有几个需要注意的,我列举如下:

  1. ObjectC的默认访问控制符是@protected的,当然你也可以定义为@private或者@public;

动态类型Dynamic Type

这里面最需要讨论的就是内省(Introspection):

  1. isKindOfClass对于有java经验的我来说很好理解,可以理解为一个类是否是一个另一个类或其父类的实例;
  2. isMemberOfClass就比较诡异了,是返回一个object是否这个类的实例,注意这里不检测继承关系,也就是说[teacher isMemberOfClass: [Teacher class]]返回YES,但是[teacher isMemberOfClass: [Person class]]返回NO。
    注意看下面的代码:
        obj1 = [[MyType alloc] init];    NSLog(@"obj1 isKindOfClass:NSObject = %@", ([obj1 isKindOfClass:[NSObject class]]) ? @"YES" : @"NO");    NSLog(@"obj1 isMemberOfClass:NSObject = %@", ([obj1 isMemberOfClass:[NSObject class]]) ? @"YES" : @"NO");    NSLog(@"obj1 isMemberOfClass:MyType = %@", ([obj1 isMemberOfClass:[MyType class]]) ? @"YES" : @"NO");

  3. ObjectC中有一种特殊的表达式:[tester respondsToSelector:@selector(test:)],其中的@selector是一个SEL类型,前面的表达式表示检查tester这个object有没有提供一个名字叫"test"的方法,注意表达式上"test"后面是有冒号的;

注意另一个问题,如果一个对象被设置为nil,那么以上的这些操作对于这个对象来说返回都是NO;


集合类型

集合类型使用的时候需要注意:

  1. NSArray/NSDictionary/NSSet等都是不可变的集合类型,意思是在创建的时候就初始化内容,并且以后不可以再增加/删除内容;
  2. NSMutableArray/NSMutableDictionary/NSMutableSet等是可变集合,分别类似于Java中的数组/Map等集合类型;





总体来说,ObjectC和C/C++/Java这些语言有类似的地方,但差异较大,过渡过来的学习曲线还是比较陡峭的,但只要抓住差异注意理解,上手还不是那么难,关键在于理解。


原创粉丝点击