OC的点语法了解一下

1,092 阅读2分钟

众所周知,OC的点语法一般用在属性的setget

//Person.h
@interface Person : NSObject

@property (copy, nonatomic) NSString *name;

@end
Person *tom = [[Person alloc] init];
tom.name = "tom";

大概原理,如果用作赋值,会寻找对应的set方法;如果用作结果,会寻找对应的get方法。最关键的是,编译器帮你检查了get方法是否存在。利用这个特点可以做哪些呢?

1.普通应用

所有没有参数的方法,都可以看作是get方法,直接使用点语法,最好有返回值。

例如

  • 初始化
Person *tom = Person.new;
Person *jack = Person.alloc.init;

NSArray *array = NSArray.array;
NSMutableArray *mutableArray = NSMutableArray.array;
...

是不是没有方括号,用起来就很爽,像Swift一样。

  • 其他没有参数的方法,类方法、对象方法都可以
// Person.h
@interface Person : NSObject
- (NSInteger)age;
@end
...

//Person.m
@implementation Person
- (NSInteger)age{return 20;}
@end

使用的话还是一样

NSLog(@"age = %ld",Person.new.age);
  • 注意

使用这种方法时,最好是有返回值,如果没有返回值,会提示一个警告Property access result unused - getters should not be used for side effects

2.链式语法

立马就想到Masonry,几乎把点语法用到极致,具体解析下怎么做到的。

为了便于理解,我把Block都用typedef定义一下。

//Person.h
@class Person;
typedef Person*_Nonnull(^PersonString)(NSString *);
typedef Person*_Nonnull(^PersonInt)(NSInteger);

@interface Person : NSObject

- (PersonString)name;
- (PersonInt)age;

@end
//Person.m
@implementation Person

- (PersonString)name{
    return ^(NSString *string){
        NSLog(@"name %@",string);
        return self;
    };
}

- (PersonInt)age{
    return ^(NSInteger integer){
        NSLog(@"age %ld",integer);
        return self;
    };
}
@end

第一步,先不要管返回值,可以确定的是,方法没有参数,可以直接使用点语法

Person *tom = Person.new;
tom.name;
tom.age;

第二步,返回值是一个Block

// typedef Person*_Nonnull(^PersonString)(NSString *);
// 可以等价于点语法获取到的返回值赋值给一个Block
PersonString blString = tom.name;

第三步,使用Block

// block返回值是Person对象,实现中使用的就是self
PersonString blString = tom.name;
tom = blString(@"tom");

PersonInt blInt = tom.age;
tom = blInt(20);

第四步,串起来的关键

所有点语法串起来的关键,就是Block的返回值就是当前对象。

去掉多余的中间变量后

tom.name(@"tom").age(20);