作者:@方秋枋(GitHub)
这篇文章是自己学习Swift的笔记与深化。希望这篇文章能够帮助已经有Objective-C经验的开发者更快地学习Swift。同时也品味到Swift的精妙之处。
结论放在开头:我认为Swift比Objective-C更优雅,更安全同时也更现代,更性感。
文章组织脉络:
-
从Objective-C到Swift的语法差异。我们熟悉的Objective-C特性在Swift中如何展现。
-
从Objective-C到Swift的进步改进。研究对比Swift在安全性,易用性上的提升,给我们带来的新编程范式。
@H_404_21@
-
strong: 在Swift中是默认的
-
weak: 通过weak关键词申明
@H_404_21@
-
readonly,readwrie 直接通过声明常量let,声明变量var的方式来指明
-
copy 通过@NSCopying指令声明。
@H_404_21@
-
nonatomic,atomic 所有的Swift properties 都是nonatomic。但是我们在线程安全上已经有许多机制,例如NSLock,GCD相关API等。个人推测原因是苹果想把这一个本来就用的很少的特性去掉,线程安全方面交给平时我们用的更多的机制去处理。
@H_404_21@
-
因此之前使用OC导致的像巧哥指出的开发争议就不再需要争执了,在Swift的世界里,我们只与property打交道。
-
并且我们在OC中init和dealloc不能使用属性self.property = XXX来进行设置的情况得以解决和统一。
@H_404_21@
-
Stored Properties和Computed properties
@H_404_21@
-
Type Properties
@H_404_21@
-
延伸:目前Swift支持的type propertis中的Stored Properties类型不是传统意义上的类变量(class variable),暂时不能通过class 关键词定义,通过static定义的类变量类似java中的类变量,是无法被继承的,父类与子类的类变量指向的都是同一个静态变量。
@H_404_21@
-
if,switch和新增的guard
-
for,while
-
break,continue
@H_404_21@
-
通过func关键词定义函数
-
返回值在->关键词后标注
-
个人觉得另外一个很棒的改进是:Default parameter values
@H_404_21@
-
Public:可以访问自己模块或应用中源文件里的任何实体,别人也可以访问引入该模块中源文件里的所有实体。通常情况下,某个接口或Framework是可以被任何人使用时,你可以将其设置为public级别。
-
Internal:可以访问自己模块或应用中源文件里的任何实体,但是别人不能访问该模块中源文件里的实体。通常情况下,某个接口或Framework作为内部结构使用时,你可以将其设置为internal级别。
- @H_404_21@
-
对于所有Stored Properties,都必须在对象被创建出来前设置好。也就是我们必须在init方法中赋好值,或是直接给属性提供一个默认值。
@H_404_21@
-
initializer严格分为Designated Initializer和Convenience Initializer 并且有语法定义。
@H_404_21@
-
枚举
@H_404_21@
-
结构体
@H_404_21@
-
id与AnyObject
@H_404_21@
-
闭包
@H_404_21@
-
错误处理
@H_404_21@
-
KVO
@H_404_21@
目录:
1.属性(property)和实例变量(instance variable)
2.控制流
3.函数
4.类与初始化(Initializers)
5.枚举与结构体
6.协议(Protocols)
7.Swift与Cocoa
8.总结
1.属性(property)和实例变量(instance variable)
Objective-C property in Swift world
在Cocoa世界开发的过程中,我们最常打交道的是property.
典型的声明为:
1
|
@property(strong,nonatomic)NSString*string;
|
而在Swift当中,摆脱了C的包袱后,变得更为精炼,我们只需直接在类中声明即可
classShape{
var
name=
"shape"
}
|
注意到这里,我们不再需要@property指令,而在Objective-C中,我们可以指定property的attribute,例如strong,weak,readonly等。
而在Swift的世界中,我们通过其他方式来声明这些property的性质。
需要注意的几点:
值得注意的是String,Array和Dictionary在Swift是以值类型(value type)而不是引用类型(reference type)出现,因此它们在赋值,初始化,参数传递中都是以拷贝的方式进行(简单来说,String,Array,Dictionary在Swift中是通过struct实现的)
延伸阅读:Value and Reference Types
然后值得注意的是,在Objective-C中,我们可以跨过property直接与instance variable打交道,而在Swift是不可以的。
例如:我们可以不需要将someString声明为property,直接使用即可。即使我们将otherString声明为property,我们也可以直接用_otherString来使用property背后的实例变量。
@interfaceSomeClass:NSObject{
NSString*someString;
}
@property(nonatomic,copy)NSString*otherString;
|
而在Swift中,我们不能直接与instance variable打交道。也就是我们声明的方式简化为简单的一种,简单来说在Swift中,我们只与property打交道。
A Swift property does not have a corresponding instance variable,and the backing store for a property is not accessed directly
小结
(不知道这一条规定,在init直接用self.property = value 的同学请自觉阅读iOS夯实:内存管理)
个人觉得这看似小小一点变动使Swift开发变得更加安全以及在代码的风格更为统一与稳定。
Swift property延伸:
在Swift中,property被分为两类:Stored Properties和Computed properties 简单来说,就是stored properties 能够保存值,而computed properties只提供getter与setter,利用stored properties来生成自己的值。个人感觉Computed properties更像方法,而不是传统意义的属性。但是这样一个特性存在,使得我们更容易组织我们的代码。
延伸阅读:computed property vs function
Swift提供了语言级别定义类变量的方法。
In C and Objective-C,you define static constants and variables associated with a type as global static variables.In Swift,however,type properties are written as part of the type’s definition,within the type’s outer curly braces,and each type property is explicitly scoped to the type it supports.
在Objective-C中,我们只能通过单例,或者static变量加类方法来自己构造类变量:
@interfaceModel
+(int)value;
+(void)setValue:(int)val;
@end
@implementationModel
staticintvalue;
+(int)value
+(void)setValue:(int)val
{@synchronized(self){value=val;}}
@end
|
//Foo.h
@interfaceFoo{
}
+(NSDictionary*)dictionary;
//Foo.m
+(NSDictionary*)dictionary
{
staticNSDictionary*fooDict=nil;
staticdispatch_once_toncePredicate;
dispatch_once(&oncePredicate,^{
//createdict
});
fooDict;
而在Swift中我们通过清晰的语法便能定义类变量:
|