学了一个多礼拜,看了 2 本书,毛都没写出来😂
主要是新入门,基础的功能都要从 0 开始写,够折腾的。不过还好蛮多 java 代码改改就能移植到 swift 里面。
遇到的几个问题吐槽一下:
粗略看了两本 swift ios app 的书,里面的内容感觉:原来写成这样的层次也可以出书(捂脸 。看完了官方的The Swift Programming Language
LANGUAGE GUIDE,稍微浅显易懂了点,算有点价值吧
没有抽象类这个玩意,不知道怎么写子类必须实现某些方法,现在用一个父类加一个 protocol 接口组合起来当做抽象类,写着别扭。
遇到问题搜 10 篇文章,有 6 篇是抄的还不带格式,另外 3 篇在讲故事,剩 1 篇终于把问题解决了。
至今没找到怎么把任意对象转成字符串,比如:obj:AnyObject, 好希望有:obj.toString(),现在用的"\(obj)"
有点丑。
一个方法注释里面明明说会引发异常,但方法并没有用 throws 把异常抛出来也没有其他措施,强制用 try 捕获会显示黄色警告,折磨死人。参考:FileHandle.write 往文件写数据这个方法,没任何返回值也没有抛任何异常,但注释说会引发异常,怕怕。也许是使用姿势不对😂
xcode 项目那个文件虽然是文本,但几乎不是人工能编写的(有点反人类)。同样是新入门,Android Studio 的项目管理就没有这么难产。
慢慢积累吧,还好 swift 语法还算正常不用去写 oc ( oc 看起来像写甲骨文,学不动)。入门到放弃!但真放弃却是不可能的,慢慢磨吧。有大佬指点迷津就更好了😊
101
noduez 2019-08-01 17:38:15 +08:00
翻页
|
102
XDDD 2019-08-01 18:12:21 +08:00 via iPhone
@finab 我是从语义的角度说明如何用字符串描述一个值。语义在 Swift 中非常重要,有不止一种方法达到目的,但语义是不同的。
如果一个值有字符串的表示形式,它应当实现 CustomStringConvertible,同时你应当使用 description。如果一个值实现了 RawRepresentable 且 RawValue==String,用 rawValue 同样可以得到字符串值,且绝大部分情况下这两种方式得到的结果是相同的。但是你不应当混用这两个方法。它们做了完全不同的事,给出完全不同的结果,并且碰巧一样。 |
103
XDDD 2019-08-01 18:20:14 +08:00 via iPhone 1
@xiangyuecn: @fvckDaybyte2 说的是异步错误( Error ),所以在回调中处理。
再重复一遍,Swift 没有 Exception,也不能处理 Exception。如果因为使用 Objective-C 而引入 Exception,需要在 Objective-C 中处理干净。 |
104
XDDD 2019-08-01 18:42:10 +08:00 via iPhone 1
其实这是很正常的逻辑,哪个语言抛了 Exception,就要用那个语言来处理。如果 Objective-C++ 抛出了 C++ 的 std::exception,用 Objective-C 的 @try 是拿不到的,需要用 C++ 的 try (同样,try 也拿不到 NSException )。
可能是 Swift 对 Objective-C 的兼容做的太好了,让很多人混淆了这两种完全不同的错误 /异常机制。 |
105
sobigfish 2019-08-01 18:46:45 +08:00
入门简单,之后的路就感觉难走了。
看 API 文档感觉太不清楚了,不知道怎么下手 |
106
XDDD 2019-08-01 19:10:25 +08:00 1
再说说被误解的最多的,String 的设计。其实很多人没有意识到,字符串及其索引的设计是一个不可能三角。以下三条在逻辑上互斥,不可能同时达到:
1. Unicode 安全(变长编码,字符组合) 2. 性能安全(以 O(1) 时间复杂度进行索引) 3. 类型安全(使用整数类型进行索引,而非 opaque 类型) 而 Swift 实现了以上三条的全部功能,怎么做到的: 1. 如果你需要以 O(1) 时间复杂度进行索引,请使用 String.Index。(抛弃了类型安全,需要用 opaque 类型来索引) 2. 如果你需要用整数类型进行索引,请手动移动下标。(不建议。抛弃了性能安全,需要 O(n) 时间复杂度) 3. 如果你需要用整数类型以 O(1) 时间复杂度进行索引,请使用 String.UTF8/16/32View。(抛弃了 Unicode 安全,直接操作码元) |
107
finab 2019-08-01 19:22:24 +08:00
@XDDD
语义的话,对于实现了 CustomStringConvertible 的类来说,\(obj) 和 String(describing:obj) 语义是一样的吧 我觉得这只是个语法糖,它们应该是语义相同语法不同而已,实际等价。 因为很明显,它就是对实现了 CustomStringConvertible 的对象调用了 objc.description 而已 我特意去搜了搜 \() 细节,但是没有找到,如果他们有啥区别还望指教一下, |
108
XDDD 2019-08-01 19:24:27 +08:00
更正 #106:解决方案 2 是将 String 转换为 Character 数组。一次性支付 O(n) 的转换开销,以后可以在保证 Unicode 安全的前提下用整数类型以 O(1) 时间复杂度进行索引。
很多人在其它语言上的经验是使用 2 或 3,隐式付出了编码转换或 Unicode 安全的代价。而在 Swift 中,你需要显式支付这一开销。 |
109
Leigg 2019-08-01 19:27:00 +08:00 via Android
iOS 现在市场上缺的是中高级开发。初级确实很难找。
|
110
XDDD 2019-08-01 19:35:52 +08:00
@finab
obj.description: 你想要获取某个值的字符串形式。 String(describing:obj): 你想要得到某个值的字符串描述。 "\(obj)": 你想要在 String 中插值。 插值是另一个概念,功能远比你看上去强大。你可以看看 SE-0228。了解一下目前 Swift 是怎么插值的。 |
111
finab 2019-08-01 19:51:04 +08:00 2
@XDDD
我去找了下 String(describing:)的实现,仅只有一行代码 /// If `instance` conforms to the `CustomStringConvertible` protocol, the result is `instance.description`. self = instance.description ” obj.description: 你想要获取某个值的字符串形式。 String(describing:obj): 你想要得到某个值的字符串描述。 “ 这两个代码实现上都是完全一样,语义自然一样吧 并且对于不实现 CustomStringConvertible 的类来讲,他们的行为也是一致的,实现代码也都一样 另外,对于任意 obj(实例对象、元类型等等), "\(obj)" == String(describing: obj) 结果都为 true 所以我才觉得, \() 就是 String(describing:obj) 的语法糖,语义完全完全等价 插值就另讲了,感觉和上面说的没关系啊 |
112
XDDD 2019-08-01 22:28:49 +08:00 via iPhone
@finab 所以我说语义而不是实现啊,如果一个值没有字符串形式(未实现 CustomStringConvertible ),会怎么样?你只能得到一个描述,而不是这个值声明自己有字符串的表示形式。
至于你觉得插值是糖,我直接抄 SE-0228 的代码了: "The price is $\(cost, format: "%.2f")" "\([.link: supportURL])Click here\([.link: nil]) to visit our support site" 你觉得它的语义是什么? |
113
finab 2019-08-01 22:39:58 +08:00 via iPhone
@XDDD
如果未实现 CustomStringConvertible,String(describing:) 与 \() 的 也是一样的,他们就是一个东西 我们不是在说的是 String(describing:) 与 \() 的语义吗?怎么老提使用 \() 做插值操作啊?- -,它们不是一个东西吧 |
114
XDDD 2019-08-01 23:04:22 +08:00
@finab 做了结果相同的两件事,和通过两种方法做一件事是不同的。
想象一下,Swift 本可以让 Any 遵循 CustomStringConvertible,并提供默认实现,你可以 override 这个实现。这样就可以对任意值执行 v.description。而现在,为什么只有 T: CustomStringConvertible 才能调用 T.description,而 Any 只能使用 String(describing: v)?因为从后一种到前一种,语意丢失了。你不知道某个类 T 是否声明自己有字符串表现形式。 T.description:T 声明自己有字符串表现形式。结果的提供者是 T。 String(describing: Any):String 声明自己可以解释 Any。结果的提供者是 String。 "\(Any)":将 Any 插值。结果是 String,所以 String 提供了解决方案。(注意,这里的 String 是类型推导出来的。这一表达式不一定得到 String。如果别的类型实现了 ExpressibleByStringInterpolation,它也可以提供解决方案) 上述三种表达完全独立。这里的结果相同是实现上的一种选择。Swift 当初甚至可以选择让这三种表达得到不同的结果。 |
115
XDDD 2019-08-01 23:11:23 +08:00
@finab \()就是插值。The Swift Programming Language 中将其称为 String Interpolation。
|