你必须重新开始

enter image description here
上一期文章发了以后,很多读者反馈说,为毛不用艾维的头像做封面啊,让我们看看这家伙是怎么虎头虎脑又充满艺术感的。好吧,今天我就截了一张艾维演讲的图给你们瞅瞅,其中他正在碎碎念视网膜屏macbook pro的那点事,刚好说了一句:你必须重新开始。中心思想就是:「哥完全抛弃了老mbp的工艺设计,外部铝合金壳和内部芯片和电路结构全部重新来过,老牛逼了,你看着办,不买是你的损失。」大概就这意思。

我觉得这句话挺好的,正好拿来作为今天的主题,回答之前积累的两个问题。

问题一:

毕业三年,java开发。在青岛拿着4500的月薪,因为兴趣自学了Objective-C,写些iPhone的小demo,没做过实际的项目。很迷茫,有时候想再回北京奋斗两年赚个首付回青岛,但害怕自己中途又受不了北京那压抑孤独的环境再次半途而废,但是在青岛这样下去实在无法安定下来,因为攒不下钱。很迷茫,不知道下一步该怎么走了,求指点。

问题二:

毕业一年,在盛大工作。工作中使用Windows为主,开发,运维,服务器都使用Windows,可我觉得自己还是喜欢玩命令行,喜欢linux,业余时间自己也在看书,学习,但是也没啥成就。请问,我这样坚持下去对本职工作也没啥用(之前目前是),请给点建议吧?

我觉得这俩问题的共性是,对现状不满意,业余时间学了点其他技术,但无法做出改变。之前我提到过《城中大盗》里的一句台词,「你知道吗,人们每天起床,做着同样的事情,他们告诉自己,有一天要改变生活,但他们从来不付诸行动。我想改变自己的生活」。想要改变生活,就要付诸行动,没有更直接的建议了。 我想这两位读者都是「80非常后」,20郎当岁,有想法有激情有大把时间,而且Nothing to lose,所以我的建议就是「尽快重新开始」。想去北京挣首付的,赶紧准备简历和火车票。不喜欢再玩windows的,一边学习Linux,一边找工作是正道。

有时候你必须重新开始,就是这样。

明天周五,打球休息!我不是自媒体人,也不靠这玩意养活自己,就别死乞白赖的写了,你们也都好好歇歇,陪陪家人朋友,别老玩手机了啊。


今天我们接着之前OC的内容,讲讲新的Objective-C在语法层面做了哪些简化。

4、语法简化

很多刚从其他编程语言转到Objective-C的同学看到长长的函数名会感到崩溃,不过我之前也提到过,这种语法让消息的传递像一个英语句子,大大增强了可读性。比如你想初始化一个浮点数,需要这么写:

NSNumber value = [NSNumber numberWithFloat:123.45f];

从这句中我们能够明确的知道代码的含义,但是,是否连简单的赋值语句也要这么处理呢?苹果在本次新特性中采用了折中的处理方式,针对很多基础类型采用了简写的方式,实现语法简化。简化以后,我们会发现从语法层面,这些简化的Objective-C更像Python和Ruby等动态语言的语法了。下面我们逐一介绍:


NSNumber

简化前的写法:

NSNumber *value;
value = [NSNumber numberWithInt:12345];
value = [NSNumber numberWithFloat:123.45f];
value = [NSNumber numberWithBool:YES];

简化后的写法:

NSNumber *value;
value = @12345;
value = @123.45f;
value = @YES;

装箱表达式也可以采用类似的写法:

NSNumber *piOverSixteen = [NSNumber numberWithDouble: ( M_PI / 16 )];
NSString *path = [NSString stringWithUTF8String: getenv("PATH")];

可以分别简写为:

NSNumber *piOverSixteen = @( M_PI / 16 );
NSString *path = @( getenv("PATH") );

对于字符串表达式来说,需要注意的是表达式的值一定不能是NULL,否则会抛出异常。

NSArray

对于NSArray的初始化来说,有非常多的写法,这里就不再一一罗列,我们直接看新的写法

NSArray *array;
array = @[];             //空数组
array = @[ a ];          //一个对象的数组
array = @[ a, b, c ];    //多个对象的数组

非常简单,再也不用记住初始化多个对象的数组时,后面还要跟一个倒霉的nil。

现在我们看一下当声明多对象的数组时,编译器是如何处理的:

array = @[ a, b, c ];

编译器生成的代码:

id objects[] = { a, b, c };
NSUInteger count = sizeof(objects)/ sizeof(id);
array = [NSArray arrayWithObjects:objects count:count];

好吧,编译器已经为我们把这些简单重复的工作都做了,我们就可以安心解决真正的问题了:)不过有一点要注意,如果a,b,c对象有nil的话,运行时会抛出异常,这点和原来的处理方式不同,编码的时候要多加小心。

NSDictionary

同样,对于字典这个数据结构来说,有很多种初始化的方式,我们来看新的写法:

NSDictionary *dict;
dict = @{};     //空字典
dict = @{ k1 : o1 };     //包含一个键值对的字典
dict = @{ k1 : o1, k2 : o2, k3 : o3 }; //包含多个键值对的字典

    最后我们总接一下容器类数据结构简化的限制:

1、采用上述写法构建的容器都是不可变的,如果需要生成可变容器,可以传递-mutableCopy消息。例如

NSMutableArray *mutablePlanets = [@[
@"Mercury", @"Venus", @"Earth",
@"Mars", @"Jupiter", @"Saturn",
@"Uranus", @"Neptune"
] mutableCopy];

2、不能对常量数组直接赋值,解决办法是在类方法(void)initialize进行赋值,如下:

@implementation MyClass

static NSArray *thePlanets;
+ (void)initialize {
    if (self == [MyClass class]) {
        thePlanets = @[
        @"Mercury", @"Venus", @"Earth",
        @"Mars", @"Jupiter", @"Saturn",
        @"Uranus", @"Neptune"
        ];
    }
}

3、没有常量字典