V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
xiangyuecn
V2EX  ›  程序员

学习 ios ( Swift ) 开发一个多礼拜的心得:入门到放弃

  •  
  •   xiangyuecn ·
    xiangyuecn · 2019-07-31 09:41:08 +08:00 · 16701 次点击
    这是一个创建于 1972 天前的主题,其中的信息可能已经有所发展或是发生改变。

    学了一个多礼拜,看了 2 本书,毛都没写出来😂

    主要是新入门,基础的功能都要从 0 开始写,够折腾的。不过还好蛮多 java 代码改改就能移植到 swift 里面。

    遇到的几个问题吐槽一下:

    1. 粗略看了两本 swift ios app 的书,里面的内容感觉:原来写成这样的层次也可以出书(捂脸 。看完了官方的The Swift Programming Language LANGUAGE GUIDE,稍微浅显易懂了点,算有点价值吧

    2. 没有抽象类这个玩意,不知道怎么写子类必须实现某些方法,现在用一个父类加一个 protocol 接口组合起来当做抽象类,写着别扭。

    3. 遇到问题搜 10 篇文章,有 6 篇是抄的还不带格式,另外 3 篇在讲故事,剩 1 篇终于把问题解决了。

    4. 至今没找到怎么把任意对象转成字符串,比如:obj:AnyObject, 好希望有:obj.toString(),现在用的"\(obj)"有点丑。

    5. 一个方法注释里面明明说会引发异常,但方法并没有用 throws 把异常抛出来也没有其他措施,强制用 try 捕获会显示黄色警告,折磨死人。参考:FileHandle.write 往文件写数据这个方法,没任何返回值也没有抛任何异常,但注释说会引发异常,怕怕。也许是使用姿势不对😂

    6. xcode 项目那个文件虽然是文本,但几乎不是人工能编写的(有点反人类)。同样是新入门,Android Studio 的项目管理就没有这么难产。

    慢慢积累吧,还好 swift 语法还算正常不用去写 oc ( oc 看起来像写甲骨文,学不动)。入门到放弃!但真放弃却是不可能的,慢慢磨吧。有大佬指点迷津就更好了😊

    116 条回复    2019-08-01 23:32:07 +08:00
    1  2  
    noduez
        101
    noduez  
       2019-08-01 17:38:15 +08:00
    翻页
    XDDD
        102
    XDDD  
       2019-08-01 18:12:21 +08:00 via iPhone
    @finab 我是从语义的角度说明如何用字符串描述一个值。语义在 Swift 中非常重要,有不止一种方法达到目的,但语义是不同的。

    如果一个值有字符串的表示形式,它应当实现 CustomStringConvertible,同时你应当使用 description。如果一个值实现了 RawRepresentable 且 RawValue==String,用 rawValue 同样可以得到字符串值,且绝大部分情况下这两种方式得到的结果是相同的。但是你不应当混用这两个方法。它们做了完全不同的事,给出完全不同的结果,并且碰巧一样。
    XDDD
        103
    XDDD  
       2019-08-01 18:20:14 +08:00 via iPhone   ❤️ 1
    @xiangyuecn: @fvckDaybyte2 说的是异步错误( Error ),所以在回调中处理。

    再重复一遍,Swift 没有 Exception,也不能处理 Exception。如果因为使用 Objective-C 而引入 Exception,需要在 Objective-C 中处理干净。
    XDDD
        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 的兼容做的太好了,让很多人混淆了这两种完全不同的错误 /异常机制。
    sobigfish
        105
    sobigfish  
       2019-08-01 18:46:45 +08:00
    入门简单,之后的路就感觉难走了。
    看 API 文档感觉太不清楚了,不知道怎么下手
    XDDD
        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 安全,直接操作码元)
    finab
        107
    finab  
       2019-08-01 19:22:24 +08:00
    @XDDD
    语义的话,对于实现了 CustomStringConvertible 的类来说,\(obj) 和 String(describing:obj) 语义是一样的吧
    我觉得这只是个语法糖,它们应该是语义相同语法不同而已,实际等价。 因为很明显,它就是对实现了 CustomStringConvertible 的对象调用了 objc.description 而已
    我特意去搜了搜 \() 细节,但是没有找到,如果他们有啥区别还望指教一下,
    XDDD
        108
    XDDD  
       2019-08-01 19:24:27 +08:00
    更正 #106:解决方案 2 是将 String 转换为 Character 数组。一次性支付 O(n) 的转换开销,以后可以在保证 Unicode 安全的前提下用整数类型以 O(1) 时间复杂度进行索引。

    很多人在其它语言上的经验是使用 2 或 3,隐式付出了编码转换或 Unicode 安全的代价。而在 Swift 中,你需要显式支付这一开销。
    Leigg
        109
    Leigg  
       2019-08-01 19:27:00 +08:00 via Android
    iOS 现在市场上缺的是中高级开发。初级确实很难找。
    XDDD
        110
    XDDD  
       2019-08-01 19:35:52 +08:00
    @finab

    obj.description: 你想要获取某个值的字符串形式。
    String(describing:obj): 你想要得到某个值的字符串描述。
    "\(obj)": 你想要在 String 中插值。

    插值是另一个概念,功能远比你看上去强大。你可以看看 SE-0228。了解一下目前 Swift 是怎么插值的。
    finab
        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) 的语法糖,语义完全完全等价


    插值就另讲了,感觉和上面说的没关系啊
    XDDD
        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"
    你觉得它的语义是什么?
    finab
        113
    finab  
       2019-08-01 22:39:58 +08:00 via iPhone
    @XDDD
    如果未实现 CustomStringConvertible,String(describing:) 与 \() 的 也是一样的,他们就是一个东西

    我们不是在说的是 String(describing:) 与 \() 的语义吗?怎么老提使用 \() 做插值操作啊?- -,它们不是一个东西吧
    XDDD
        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 当初甚至可以选择让这三种表达得到不同的结果。
    XDDD
        115
    XDDD  
       2019-08-01 23:11:23 +08:00
    @finab \()就是插值。The Swift Programming Language 中将其称为 String Interpolation。
    finab
        116
    finab  
       2019-08-01 23:32:07 +08:00 via iPhone
    @XDDD
    嗯,我是说你之前举例的\(x, ...) 这种不同形式的语法糖和我说的无关

    然后总结下
    String(describing:obj) 与 \(obj)

    使用上,obj 能做 String(describing:)的参数,就也能这样写 \(obj),反之亦然

    返回值,它们也永远一样

    实现,一样

    然后他们语义不一样是这样嘛,你是不是在骗我😓
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1069 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 19:21 · PVG 03:21 · LAX 11:21 · JFK 14:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.