作者HuangJC (吹笛牧童)
看板MacDev
标题Re: [问题] 请问 IPC - 更改需求至 tcp/ip ; Object C 与 Xcode
时间Tue Feb 11 16:05:46 2014
记得以前偶尔会和朋友分辨清楚:
Visual C 是个产品
而 C 是种语言
Ansi C 是个标准
以上也许未达精确
我的意思是,讨论时我很能容错,因为我也常错
所以只要听得懂朋友说什麽,我们就继续讨论下去
朋友要混用三个词我完全不介意;除非必需分辨它了
现在我又碰到这状况了:
Object C 是种语言
Xcode 是个产品(这种语言的 compiler)
为什麽呢? 因为我买了本书,叫做 Object - C 无痛入门
里面至少有两点就踢中铁板
1.@synthesize 保留字
书上说用这个取代 @property, 就可以连 get set 的本体程式都不用写
但如果写了,就以我们写的为准;自动判断,很方便
不过 Xcode 上我实测,打了 @synthesize 就 build fail
(更正,不会 build fail, 是我打错地方了;我打在 interface 里)
而 @property 就有自动补上 get set 本体的能力了 (其实这样更好用)
2.书上说, Object C 的 class 可以没有 base class,
并没预设一定要从 NSObject 继承起
实测上, Xcode 无法接受没有 base class, 一定会 build fail
就举以上两例,也许我可以说, Object C 这本书,讲的是这个语言的标准
而 Xcode 是一个实作这语言的 compiler,它有些许不同
更甚至,我担心的是 Xcode 有版本差异(有版本当然会有差异;我意思是,不向旧版相容)
因为我从网路上抓到的 sample code 要 build 过就好辛苦
嗯,今天还没 build 过
其实我今天赶的 dead line 是要写出 tcp/ip server & client
剩没几个小时了 Orz
主管要求用 tcp/ip 实测能不能跨 task, 可以的话当然可以做 ipc
至於两个程式无法同时执行,这我们可以克服
因为我们是 GPS 程式,有背景执行的权限..
--
活动/美食计划
兰屿 鱼白 胜兴车站 星月天空 武陵 草岭古道
嘉义阿里山小火车 保龄球 司马库斯
手包水饺 日月潭缆车 合欢攻顶 马祖
盐山 南庄 澎湖 溪头/松林町 南投天梯
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 60.251.197.63
1F:推 johnlinvc:书有点旧了,三年前确实一定要打@synthesize 02/11 16:40
2F:→ HuangJC:原来如此.. 真有 02/11 16:46
3F:→ HuangJC:我快被 ARC 搞死了,这东西好像挺新.. 02/11 16:46
4F:→ HuangJC:这本书就没教 ARC (应该没教吧) 02/11 16:47
5F:推 johnlinvc:书里面如果还有retain 关键字的话就可以当古文物了XD 02/11 16:56
6F:→ HuangJC:那我去加玛雅人好友好了 Orz 02/11 16:57
顺便讨论一下 gc
对於自动 reference count 的作法
其实我从 VC++ / MFC 转过来,并不陌生
首先是 CString 物件,它就是自动管理记忆体
当无人 reference 它时,才释放
接下来是 COM,虽然我 COM 始终学不好
只好模仿它做一些类似的 class
但教导 COM 的书里就有完整介绍 reference count
其实 CString 也是用这概念
大致上,有人引用就 ref + 1
失去引用就 ref - 1
这点,并没由 C++ 直接支援
而是由改写一堆 operater function 达成
(比如 CString a = str
这样会使 str 计数加一,那可能是改写 constructor,可能是改写 operator =
总之要改写的点很多,但繁复的改写後就可以打造出 reference count)
COM MODEL 比较方便的是,继承就拥有这些
如果不用COM,也可以经由 template 来打造自己的 class
(同样的我也没学好,所以我无法弄出自己的自动记忆体管理物件;
都是半调子,可能只在 destructor 管理一下)
学到 Android/java 时,挺开心的,有 gc
对物件的理解是, 它是语言直接支援 reference count
但为什麽要跟我说, gc 是有一个独立的 thread 在做呢?
如果有 refernce count,那就在 count 归零时释放就好
不必另一个 thread 啊..
然後现在到 Object C, 又跟我说它的 ARC 是由 compiler 实作
走 reference count!! 不必再一个 thread
(但也因此限制了我某些用法,我还搞不懂为何被限制)
我已经混乱了啊~~~
※ 编辑: HuangJC 来自: 60.251.197.63 (02/11 17:07)
7F:推 johnlinvc:java的不是ref count, 他是跑generation GC 02/11 17:36
8F:→ johnlinvc:也就是直接从object root去traverse,砍了走不到的 02/11 17:38
9F:→ johnlinvc:generation指的是有分粗略GC和仔细GC,用来加快速度 02/11 17:39
10F:→ HuangJC:喔,因为所有物伴有同一个根部 class,这变得不难理解!! 02/11 18:28
11F:→ HuangJC:那我如果又有幸回到 C++,我写这个就好了,安全又省事 XD 02/11 18:29
12F:→ atst2:arc跟gc不同,不要搞混了. reference count也跟gc不同 02/11 18:54
13F:→ atst2:学究一点的讲法,rc/gc是记忆体以及所有权管理的不同策略 02/11 18:56
14F:→ atst2:想要达到的目的类似, 但做法不同. arc则是自动化的rc 02/11 18:56
我可以这样说吗?
CString, COM
都是有写好的函式库, frame work
它所用的 C++ 语法仍然是标准的;它没有扩充或改写 C++
它只是要预先引入函式库而已
那这算 rc
15F:→ atst2:是由编译器用前置处理器自动帮你加上retain/release 02/11 18:57
目前我只知道 C 的这种前置处理器
它要自己写想去替换什麽,或者 #if #else, 也不过是协助 user 去实现 code 管理
有更广义的前置处理器吗? 或就指用这个?
其实要怎麽说它是前置处理器呢?
C 的那个很明确,因为被 #if #else 框出去不用的 code
就保障百分百不会影响流程,不会影响 code size
完全和执行期无关,也完全和後期 compile time 无关了
这在我们修改过於巨大,不明来源,前辈留下的 source code 时很有用
因为我保证是我干的就我干的,我没干的也保证不会影响别人
可以百分百没有 side effect
当专案进行中,已经有产品 release 又要改 code
主管只接受这种修改
可以说,用一个全域布林变数
if ( bNew )
newcode();
else
oldcode();
这样,虽然也漂亮,但主管就不接受了
因为多一个 byte 就不知会不会影响堆叠,根本不想冒险
那麽 ARC 是怎麽加,所谓前置处理器加的
我实在想见识见识
或者它不是 C 的那种前置处理器,是更广义的?
谢谢
※ 编辑: HuangJC 来自: 60.251.197.63 (02/11 19:30)
16F:→ atst2:在编译前处理, 就算前置处理器了. 跟C的差异只在处理的目的 02/11 20:19
17F:→ atst2:不同. 详情可以参考一下wiki对preprocessor的说明. 02/11 20:19
18F:→ atst2:arc简单说就是剖析你的程式, 判断在那些地方应该要加上 02/11 20:20
19F:→ atst2:retain,release等字串. 加完字串後,还是交给objective-c的 02/11 20:21
20F:→ atst2:编译器来处理. 02/11 20:21
-----
推 johnlinvc:java的不是ref count, 他是跑generation GC 02/11 17:36
→ johnlinvc:也就是直接从object root去traverse,砍了走不到的 02/11 17:38
本来想说在 C++ 以後也可以自己写这种逻辑
昨天突然发现我写不出来
class C1 : RootClass{
}
C1 I1 = new C1();
像这样, RootClass 里要有什麽?
我可以在 C1 的 constructor 去注册它自己
方法也不用自己写,从 RootClass 继承就好
class RootClass {
RootClass() {
Register(this); // 就简单把 this 指标存入一个 list 里就好
}
}
所以以後从 RootClass 里就可以搜寻到所有物件
但我要怎麽知道某物件没有人参考到它了?
I1 = null;
像这行就代表 I1 不再使用原物件,原物件可以删除了
除非我 traverse 的方式不只寻找所有物件,还有寻找所有变数
比如维护两个 list,
list1 里面是物件,如上例中的 C1 物件
list2 里面是变数,如上例中的 I1
一开始 I1 = C1, 所以 list1 中的物件有被使用到
後来 I1 = null, 所以把 list2 中的物件都绕完後,
发现 list1 里有物件没人使用了,删除
这样似乎可行,问题是我怎麽取得 &I1,这岂不是要在产生变时数马上去注册它
C1 I1 = new C1();
Register(&I1);
这种麻烦事还要自己做,而无法写在 RootClass 内变成 transparent
那岂不是说一定要 compiler 支援?
因为 compiler 才知道我何时又要求一个变数了,何时变数从堆叠弹出了
(退出函式时, 变数 I1 的生命周期结束,虽然没有 I1 = null 这句, 但一样可以删除了)
user 自己写总是会漏勾的
与其如此,看到 CString 的记忆体管理那麽完整,使用时可以忘了它的存在
我觉得还是补上一些 method,内建 reference count 简单多了
※ 编辑: HuangJC 来自: 60.251.197.63 (02/13 12:56)
※ 编辑: HuangJC 来自: 60.251.197.63 (02/13 19:46)