求教iOS开发知识


做iPhone/iPad需要哪些知识??

洒家只知道要会 Objective-c,
熟悉 iOS SDK
工具是 xcode

基础的 数据结构、算法、多线程、Socket、XML ,这些应该也是要掌握的,
还有些啥?

或者,能不能细化一下Objective-c的重要技术点?谢谢。。

ios xcode objective-c

最無国皇帝 10 years, 6 months ago

作为一个半路转学ios开发的开发者,从我两个月的开发经历来看,objective-c一点也不难。我的开发的程序经历了如下的变迁,我也趁机来总结下得失

最弱智的hello world

从xcode新建一个project,然后打开窗口编辑器(Interface Builder,简称IB),拖入一个UILabel组件,写上"Hello World",这样就算完了。

了解代码的组成

虽然它的名字叫"objective-c",但似乎一点也不同于我以前写过的c语言,里面充满了无数让菜鸟迷惑的潜规则。

  1. 为什么用 #import 而不用 #include ?
  2. @property 是什么东西?它括号里面的 (strong, nonatomic) 又会 发生什么奇怪的化学反应 ?为什么我在 @interface 里声明了属性,还要再 @property ?它和 @synthesize 又有什么关系?

这一阶段基本上集中了很多小白的问题,幸运的是这些问题都很容易在网上找到答案,而且如果你有其它的语言基础的话也会很容易理解这些语法。

我在这一阶段写出的代码基本惨不忍睹,所有的代码都放在一个controller里,一个是因为我懒,另一个是因为我还没有掌握objective-c开发世界里的编码风格,所以索性就不要风格了。你的代码里可能充满了 IBOutlet 或者 IBAction

不过只要你的代码能够工作,那么一切都是值得的。

初窥精髓

在cocoa框架里的一大精髓就是 delegate ,中文翻译为"委托"模式(本人自创直译其为"代理"模式)。虽然这一模式并不是cocoa的独创,但也是它运用的最好的地方之一。 delegate 模式解决了 controller view 之间的交互问题。

在我写代码的时候,往往发现只要 seDelegate ,就会发生很多很美妙的事情。另外你会发现,ios提过的这些基本组件已经无法满足你对交互的要求了,这时候你可能需要开始扩展它的一些基本组件。

扩展它的基本组件是件很简单的事情,sdk中也预留了很多接口供我们 override 。一般这时候的你看着以前自己写的丑陋的代码,会忍不住开始重构它,放手去重构吧。

得心应手

其实了解了 objective-c 世界的一些潜规则以后,除了对它API的掌握,它就基本已经成为一种普通的工具语言了。

但要注意的是,xcode 4以后引入了ARC,也就是自动引用计数这个玩意,并且它默认是打开的。可能会给你造成一些困扰。很多初学者会担心交由系统管理内存会造成内存的浪费,其实了解它的原理后,发现它的实现非常简单,其实就是当一个对象的没有人引用时,系统就自动把它 release 掉。而交给系统来处理也可以避免内存碎片的形成,但如果你需要频繁在一块内存区域读写内存,比如自己实现的消息队列之类的,建议自己通过 struct 来实现。

但是如果你定义这样一个struct

typedef struct _Test {

    NSString *name;

} Test;

编译器会无情的告诉你,在struct里无法引用objective-c的对象,为什么?因为ARC无法控制到struct里的引用计数。但是如果你非要在struct里引用一个对象怎么办,你可以使用 void * 来保存一个指针

typedef struct _Test {
    void *namePtr;
} Test;

// malloc的指针也不会被arc, 注意自己释放
Test test = (Test *)malloc(sizeof(Test));
test.namePtr = (__bridge void *)[NSString stringWithString:@"Hello"];

但有一个问题,在上面的代码中 [NSString stringWithString:@"Hello"] 这只是个临时变量,虽然它被struct的指针指向了,但是前面说到了,这不会引起 ARC 的引用计数。

那么就是说ARC会认为没有人引用这个变量,如果不出意外,这段代码执行玩以后,这片内存会被系统回收。如果你再次调用这个指针指向的内存,只会得到一个 EXC_BAD_ACCESS 错误。

解决方法其实很简单,我们可以强制让ARC计数,比如在当前的 @interface 里设置一个变量指向这个string,这样它就不会被释放了

@interface TestObj : NSObject {
    NSString *name;
}

- (void)initName
{
    name = [NSString stringWithString:@"Hello"];    // 强制引用
    Test test = (Test *)malloc(sizeof(Test));
    test.namePtr = (__bridge void *)name;
}

OK, 说了这么多比较乱,最后还吐槽了下ARC。最后的结论就是上手是很快的,但学好也需要自己钻研。

命莲寺忘却缘起 answered 10 years, 6 months ago

Your Answer