为啥 Objective-C 很难

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥 Objective-C 很难相关的知识,希望对你有一定的参考价值。

参考技术A 移动端开发的难度非常高
需要掌握的东西也很多
OC是很早就出现的语言,语法本身很多的问题,开发过程中,就会影响你的应用的稳定
所以出现了swift来淘汰和替换OC
参考技术B 语法
先说说编程语言是什么。所谓编程语言就是一种人可以读得懂的程序代码。一门编程语言通常包含一系列内容:语法(语句书写和声明的规则)和语义(以达成某些任务为目标,把语句和声明有效的结合起来)。
大部分(通常情况下)编程语言在方法调用上都是类似C语言的风格,访问类成员采用.语法。(也就是C中的structs)。虽然这些语言一般都有各自己定义类的方式(Java和C#或C++还是不大相同的),但是追究到语言的诸多细节还都是很相似的。每当人们开始接触一门新的编程语言的时候,如果它的语法看起来很似曾相识,会让学习者觉得很舒服。像大多数人都是有C语法背景的,所以要学习一门类C语法的语言的话,第一观感会很亲切。
单从语法角度来看,Objective-C可谓**别具一格**。它的语法太特别了,碍于它语法的另类,很多人没有耐心去深究它的语义,而它的语义恰恰与C++,Java等语言没什么区别。
像Python和Ruby这些所谓”古怪”的语言都更容易上手,仅仅是因为它们可以通过.语法来进行方法调用和访问类成员。而且人们通常能够迅速习惯用缩进来代替花括号。
bjective-C是C的超集,它其实是一门很cool的编程语言,但是由于其自身的某些特点,相较于其他现代编程语言,人们会觉得Objective-C很古老。作为C的超集,Objectivec-C在C的基础上扩展了一系列非常规的特性,这恰恰增加了Objective-C的复杂度。
Objective-C是一门大型语言。下此定义的出发点是:它的语法十分繁复。实际上,苹果已经在加大对Objective-C瘦身的力度,比如说,虽然速度缓慢但是终究还是完成了头文件去标准C风格的过渡。而且,苹果还为Objective-C做了不少改进,增加了许多新特性,使得Objective-C的代码更加简练
Runtime
Objective-C是动态运行的,可能单单从其与C的渊源这个角度来看这个特性并不那么直观。由于不需要直接编写汇编码,C语言自身是一门变化较低的语言,鉴于Objective-C是C的超集,我们很容易将Objective-C的稳定性趋向于C,但现实际上,Objective-C是动态运行的且灵活性相当高的语言。Objective-C支持函数柯里化(function currying),支持反射机制,可以在运行时动态地为类添加或移除方法。
Framework
使用Objective-C构建apps完全离不开Cocoa/Cocoa Touch框架。就好像用Ruby开发web应用离不开Rails一样。
Cocoa/Cocoa-Touch是庞大的框架。要真正的驾驭它就只能靠熟能生巧了。但这个熟悉它的过程常常使很多新的学习者退缩。
History
一直以来,苹果都在不停的推动着围绕Objective-C语言开发体系的进步,像Objective-C runtime,Cocoa/Cocoa Touch框架以及针对Objective-C的编译器等一系列更高层面设计的交叉重叠使得Objective-C不仅仅是一个语言这么简单。
所以当学习Objective-C的时候,不能孤立的去学习这门语言、某些框架、它的运行机制或编译器,而是要把他们融会贯通。比如说现在Objective-C集成的ARC(Automatic Reference Counting)机制就涉及到了语义(不需要显示调用dealloc了)层面、编译器层面(显而易见)、以及对Cocoa/Cocoa Touch框架的命名约定等内容。
未来
从目前掌握的信息来看,过去的四年来苹果一直在尝试降低Objective-C语言的复杂度。淘汰手动内存管理以及C标准头文件,引入更符合当下编程语言潮流的ARC机制,还有通过.语法来访问属性的getter/setter方法等等都是为了降低Objective-C的学习成本。但是即便如此,Objective-C仍然是具备一定学习门槛的开发语言,它的热度完全那些基于Objective-C编写的热门ios应用带起来的。本回答被提问者和网友采纳

Objective-C,为啥这些 NSArrays 不匹配?

【中文标题】Objective-C,为啥这些 NSArrays 不匹配?【英文标题】:Objective-C, why do these NSArrays not match?Objective-C,为什么这些 NSArrays 不匹配? 【发布时间】:2012-07-10 01:44:44 【问题描述】:

我有两个要比较的 NSArray — 在 NSLog 输出中它们看起来相同,但不知何故它们并不相等。如果我将 NSArray 转换为 NSString 我会得到相同的结果。将它们与自己进行比较将是平等的。如何确定为什么一和二不相等?谢谢。

- (void)confused:(NSArray *)two 

    NSArray *one = [NSArray arrayWithObjects:@"16777223", @"7", nil];
    NSArray *two = [[NSBundle bundleWithPath:@"/path/to/bundle"] executableArchitectures];

    // NSArray "two" shows as 16277223, 7 in NSLog

    if ([two firstObjectCommonWithArray:(NSArray *)one])
    
        NSLog(@"- it's equal %@ %@", one, two);
        // if array one matches array two then this will output
    
    else 
        NSLog(@"- it's NOT equal %@ %@", one, two);
    

    return;

这是控制台的输出:

myApp (
    16777223,
    7
)
myApp (
    16777223,
    7
)
myApp - it's NOT equal (
    16777223,
    7
)(
    16777223,
    7
)

【问题讨论】:

可否包括two的创建? 和我的另一个问题'[[NSBundle bundleWithPath:@"/path/to/bundle"] executableArchitectures]'直接相关;所以上面例子中 NSArray one 的值是@"16777223",@"7",nil 哦。该方法返回NSNumber 的数组,而不是NSString。那是你的问题。 是的,如果对象类型不同,即使它们产生相同的 description 转储,它们也不太可能进行相同的比较。 好的,我已经更新了如何创建 NSArray 2 的问题。所以问题真的是如何表示 NSArray 1 以使其等于 2? 【参考方案1】:

-[NSBundle executableArchitectures] 返回一个由NSNumber 对象组成的数组,而不是NSString 对象,因此您传入的数组中没有字符串。如果你改变了

NSArray *one = [NSArray arrayWithObjects:@"16777223",@"7", nil];

NSArray *one = [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInteger:NSBundleExecutableArchitectureX86_64], 
                                         [NSNumber numberWithUnsignedInteger:NSBundleExecutableArchitectureI386], 
                  nil];

您的代码应该可以工作。

【讨论】:

哇,所以内置了 mach-o 部分?我不知道,很酷。我现在就试试——谢谢! 你的意思是NSBundleExecutableArchitectureX86_64?这些只是您导入的名称。它们在 NSBundle.h 中定义,就在声明 executableArchitectures 的上方。 当你像这样使用来自enum 的值时,总是最好用它们的名字而不是值来引用它们——它提高了可读性并防止值的可能变化(但不太可能)。 == 比较 NSArray 对象在内存中的位置;那些肯定不会相等。不过,firstObjectCommonWithArray:[one isEqual:two] 应该都可以工作。不是吗? firstObjectCommonWithArray :返回数组中第一个相同的对象,它不是用于相等检查。

以上是关于为啥 Objective-C 很难的主要内容,如果未能解决你的问题,请参考以下文章

获取根 ViewController - Objective-C

在 Objective-C 代码中使用 Swift 的缺点?

在 Objective-C 代码中使用 Swift 的缺点?

Swift对比Objective-C

ARC 不允许将非 Objective-C 指针类型“const char *”隐式转换为“id”

为啥 Objective-C 对象必须动态分配?