Objective-C代码学习大纲(3)

2011-05-11 14:06 佚名 otierney 字号:T | T

本文为台湾出版的《Objective-C学习大纲》的翻译文档,系统介绍了Objective-C代码,很多名词为台湾同胞特指词汇,在学习时仔细研读才能体会。

AD:干货来了,不要等!WOT2015 北京站演讲PPT开放下载!

详细说明...

多重参数

目前为止我还没展示如何传递多个参数。这个语法乍看之下不是很直觉,不过它却是来自一个十分受欢迎的 Smalltalk 版本。

  1. Fraction.h
  2. ...
  3. -(void) setNumerator: (int) n andDenominator: (int) d;
  4. ...
  5. Fraction.m
  6. ...
  7. -(void) setNumerator: (int) n andDenominator: (int) d {
  8. nnumerator = n;
  9. ddenominator = d;
  10. }
  11. ...
  12. main.m
  13. #import
  14. #import "Fraction.h"
  15. int main( int argc, const char *argv[] ) {
  16. // create a new instance
  17. Fraction *frac = [[Fraction alloc] init];
  18. Fraction *frac2 = [[Fraction alloc] init];
  19. // set the values
  20. [frac setNumerator: 1];
  21. [frac setDenominator: 3];
  22. // combined set
  23. [frac2 setNumerator: 1 andDenominator: 5];
  24. // print it
  25. printf( "The fraction is: " );
  26. [frac print];
  27. printf( "\n" );
  28. // print it
  29. printf( "Fraction 2 is: " );
  30. [frac2 print];
  31. printf( "\n" );
  32. // free memory
  33. [frac release];
  34. [frac2 release];
  35. return 0;
  36. }

output

  1. The fraction is: 1/3
  2. Fraction 2 is: 1/5

这个 method 实际上叫做 setNumerator:andDenominator:

加入其他参数的方法就跟加入第二个时一样,即 method:label1:label2:label3: ,而唿叫的方法是 [obj method: param1 label1: param2 label2: param3 label3: param4]

Labels 是非必要的,所以可以有一个像这样的 method:method:::,简单的省略 label 名称,但以 : 区隔参数。并不建议这样使用。

建构子(Constructors)

  1. Fraction.h
  2. ...
  3. -(Fraction*) initWithNumerator: (int) n denominator: (int) d;
  4. ...
  5. Fraction.m
  6. ...
  7. -(Fraction*) initWithNumerator: (int) n denominator: (int) d {
  8. self = [super init];
  9. if ( self ) {
  10. [self setNumerator: n andDenominator: d];
  11. }
  12. return self;
  13. }
  14. ...
  15. main.m
  16. #import
  17. #import "Fraction.h"
  18. int main( int argc, const char *argv[] ) {
  19. // create a new instance
  20. Fraction *frac = [[Fraction alloc] init];
  21. Fraction *frac2 = [[Fraction alloc] init];
  22. Fraction *frac3 = [[Fraction alloc] initWithNumerator: 3 denominator: 10];
  23. // set the values
  24. [frac setNumerator: 1];
  25. [frac setDenominator: 3];
  26. // combined set
  27. [frac2 setNumerator: 1 andDenominator: 5];
  28. // print it
  29. printf( "The fraction is: " );
  30. [frac print];
  31. printf( "\n" );
  32. printf( "Fraction 2 is: " );
  33. [frac2 print];
  34. printf( "\n" );
  35. printf( "Fraction 3 is: " );
  36. [frac3 print];
  37. printf( "\n" );
  38. // free memory
  39. [frac release];
  40. [frac2 release];
  41. [frac3 release];
  42. return 0;
  43. }

output

  1. The fraction is: 1/3
  2. Fraction 2 is: 1/5
  3. Fraction 3 is: 3/10

@interface 裡的宣告就如同正常的函式。

@implementation 使用了一个新的关键字:super

如同 Java,Objective-C 只有一个 parent class(父类别)。

使用 [super init] 来存取 Super constructor,这个动作需要适当的继承设计。

你将这个动作回传的 instance 指派给另一新个关键字:self。Self 很像 C++ 与 Java 的 this 指标。

if ( self ) 跟 ( self != nil ) 一样,是为了确定 super constructor 成功传回了一个新物件。nil 是 Objective-C 用来表达 C/C++ 中 NULL 的方式,可以引入 NSObject 来取得。

当你初始化变数以后,你用传回 self 的方式来传回自己的位址。

预设的建构子是 -(id) init。

技术上来说,Objective-C 中的建构子就是一个 "init" method,而不像 C++ 与 Java 有特殊的结构。

存取权限

预设的权限是 @protected

Java 实作的方式是在 methods 与变数前面加上 public/private/protected 修饰语,而 Objective-C 的作法则更像 C++ 对于 instance variable(译注:C++ 术语一般称为 data members)的方式。

  1. Access.h
  2. #import
  3. @interface Access: NSObject {
  4. @public
  5. int publicVar;
  6. @private
  7. int privateVar;
  8. int privateVar2;
  9. @protected
  10. int protectedVar;
  11. }
  12. @end
  13. Access.m
  14. #import "Access.h"
  15. @implementation Access
  16. @end
  17. main.m
  18. #import "Access.h"
  19. #import
  20. int main( int argc, const char *argv[] ) {
  21. Access *a = [[Access alloc] init];
  22. // works
  23. a->publicVar = 5;
  24. printf( "public var: %i\n", a->publicVar );
  25. // doesn't compile
  26. //a->privateVar = 10;
  27. //printf( "private var: %i\n", a->privateVar );
  28. [a release];
  29. return 0;
  30. }

output

  1. public var: 5

如同你所看到的,就像 C++ 中 private: [list of vars] public: [list of vars] 的格式,它只是改成了@private, @protected, 等等。

Class level access

  1. ClassA.h
  2. #import
  3. static int count;
  4. @interface ClassA: NSObject
  5. +(int) initCount;
  6. +(void) initialize;
  7. @end
  8. ClassA.m
  9. #import "ClassA.h"
  10. @implementation ClassA
  11. -(id) init {
  12. self = [super init];
  13. count++;
  14. return self;
  15. }
  16. +(int) initCount {
  17. return count;
  18. }
  19. +(void) initialize {
  20. count = 0;
  21. }
  22. @end
  23. main.m
  24. #import "ClassA.h"
  25. #import
  26. int main( int argc, const char *argv[] ) {
  27. ClassA *c1 = [[ClassA alloc] init];
  28. ClassA *c2 = [[ClassA alloc] init];
  29. // print count
  30. printf( "ClassA count: %i\n", [ClassA initCount] );
  31. ClassA *c3 = [[ClassA alloc] init];
  32. // print count again
  33. printf( "ClassA count: %i\n", [ClassA initCount] );
  34. [c1 release];
  35. [c2 release];
  36. [c3 release];
  37. return 0;
  38. }

output

  1. ClassA count: 2
  2. ClassA count: 3

static int count = 0; 这是 class variable 宣告的方式。其实这种变数摆在这裡并不理想,比较好的解法是像 Java 实作 static class variables 的方法。然而,它确实能用。

+(int) initCount; 这是回传 count 值的实际 method。请注意这细微的差别!这裡在 type 前面不用减号 - 而改用加号 +。加号 + 表示这是一个 class level function。(译注:许多文件中,class level functions 被称为 class functions 或 class method)

存取这个变数跟存取一般成员变数没有两样,就像 ClassA 中的 count++ 用法。

+(void) initialize method is 在 Objective-C 开始执行你的程式时被唿叫,而且它也被每个 class 唿叫。这是初始化像我们的 count 这类 class level variables 的好地方。

异常情况(Exceptions)

注意:异常处理只有 Mac OS X 10.3 以上才支援。

  1. CupWarningException.h
  2. #import
  3. @interface CupWarningException: NSException
  4. @end
  5. CupWarningException.m
  6. #import "CupWarningException.h"
  7. @implementation CupWarningException
  8. @end
  9. CupOverflowException.h
  10. #import
  11. @interface CupOverflowException: NSException
  12. @end
  13. CupOverflowException.m
  14. #import "CupOverflowException.h"
  15. @implementation CupOverflowException
  16. @end
  17. Cup.h
  18. #import
  19. @interface Cup: NSObject {
  20. int level;
  21. }
  22. -(int) level;
  23. -(void) setLevel: (int) l;
  24. -(void) fill;
  25. -(void) empty;
  26. -(void) print;
  27. @end
  28. Cup.m
  29. #import "Cup.h"
  30. #import "CupOverflowException.h"
  31. #import "CupWarningException.h"
  32. #import
  33. #import
  34. @implementation Cup
  35. -(id) init {
  36. self = [super init];
  37. if ( self ) {
  38. [self setLevel: 0];
  39. }
  40. return self;
  41. }
  42. -(int) level {
  43. return level;
  44. }
  45. -(void) setLevel: (int) l {
  46. llevel = l;
  47. if ( level > 100 ) {
  48. // throw overflow
  49. NSException *e = [CupOverflowException
  50. exceptionWithName: @"CupOverflowException"
  51. reason: @"The level is above 100"
  52. userInfo: nil];
  53. @throw e;
  54. } else if ( level >= 50 ) {
  55. // throw warning
  56. NSException *e = [CupWarningException
  57. exceptionWithName: @"CupWarningException"
  58. reason: @"The level is above or at 50"
  59. userInfo: nil];
  60. @throw e;
  61. } else if ( level < 0 ) {
  62. // throw exception
  63. NSException *e = [NSException
  64. exceptionWithName: @"CupUnderflowException"
  65. reason: @"The level is below 0"
  66. userInfo: nil];
  67. @throw e;
  68. }
  69. }
  70. -(void) fill {
  71. [self setLevel: level + 10];
  72. }
  73. -(void) empty {
  74. [self setLevel: level - 10];
  75. }
  76. -(void) print {
  77. printf( "Cup level is: %i\n", level );
  78. }
  79. @end
  80. main.m
  81. #import "Cup.h"
  82. #import "CupOverflowException.h"
  83. #import "CupWarningException.h"
  84. #import
  85. #import
  86. #import
  87. #import
  88. int main( int argc, const char *argv[] ) {
  89. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  90. Cup *cup = [[Cup alloc] init];
  91. int i;
  92. // this will work
  93. for ( i = 0; i < 4; i++ ) {
  94. [cup fill];
  95. [cup print];
  96. }
  97. // this will throw exceptions
  98. for ( i = 0; i < 7; i++ ) {
  99. @try {
  100. [cup fill];
  101. } @catch ( CupWarningException *e ) {
  102. printf( "%s: ", [[e name] cString] );
  103. } @catch ( CupOverflowException *e ) {
  104. printf( "%s: ", [[e name] cString] );
  105. } @finally {
  106. [cup print];
  107. }
  108. }
  109. // throw a generic exception
  110. @try {
  111. [cup setLevel: -1];
  112. } @catch ( NSException *e ) {
  113. printf( "%s: %s\n", [[e name] cString], [[e reason] cString] );
  114. }
  115. // free memory
  116. [cup release];
  117. [pool release];
  118. }

output

  1. Cup level is: 10
  2. Cup level is: 20
  3. Cup level is: 30
  4. Cup level is: 40
  5. CupWarningException: Cup level is: 50
  6. CupWarningException: Cup level is: 60
  7. CupWarningException: Cup level is: 70
  8. CupWarningException: Cup level is: 80
  9. CupWarningException: Cup level is: 90
  10. CupWarningException: Cup level is: 100
  11. CupOverflowException: Cup level is: 110
  12. CupUnderflowException: The level is below 0

NSAutoreleasePool 是一个记忆体管理类别。现在先别管它是干嘛的。

Exceptions(异常情况)的丢出不需要扩充(extend)NSException 物件,你可简单的用 id 来代表它: @catch ( id e ) { ... }

还有一个 finally 区块,它的行为就像 Java 的异常处理方式,finally 区块的内容保证会被唿叫。

Cup.m 裡的 @"CupOverflowException" 是一个 NSString 常数物件。在 Objective-C 中,@ 符号通常用来代表这是语言的衍生部分。C 语言形式的字串(C string)就像 C/C++ 一样是 "String constant" 的形式,型别为 char *。

Objective-C代码学习大纲(3)的更多相关文章

  1. Objective-C代码学习大纲(6)

    2011-05-11 14:06 佚名 otierney 字号:T | T 本文为台湾出版的<Objective-C学习大纲>的翻译文档,系统介绍了Objective-C代码,很多名词为台 ...

  2. Objective-C代码学习大纲(5)

    2011-05-11 14:06 佚名 otierney 字号:T | T 本文为台湾出版的<Objective-C学习大纲>的翻译文档,系统介绍了Objective-C代码,很多名词为台 ...

  3. Objective-C代码学习大纲(4)

    2011-05-11 14:06 佚名 otierney 字号:T | T 本文为台湾出版的<Objective-C学习大纲>的翻译文档,系统介绍了Objective-C代码,很多名词为台 ...

  4. Objective-C代码学习大纲(2)

    2011-05-11 14:06 佚名 otierney 字号:T | T 本文为台湾出版的<Objective-C学习大纲>的翻译文档,系统介绍了Objective-C代码,很多名词为台 ...

  5. Objective-C代码学习大纲(1)

    2011-05-11 14:06 佚名 otierney 字号:T | T 本文为台湾出版的<Objective-C学习大纲>的翻译文档,系统介绍了Objective-C代码,很多名词为台 ...

  6. 大数据Python学习大纲

    最近公司在写一个课程<大数据运维实训课>,分为4个部分,linux实训课.Python开发.hadoop基础知识和项目实战.这门课程主要针对刚从学校毕业的学生去应聘时不会像一个小白菜一样被 ...

  7. JVM学习——学习方法论&学习大纲

    2020年02月06日22:25:51 完成了Springboot系列的学习和Kafka的学习,接下来进入JVM的学习阶段 深入理解JVM 学习方法论 如何去学习一门课程--方法论 多讨论,从别人身上 ...

  8. u-boot代码学习内容

    前言  u-boot代码庞大,不可能全部细读,只能有选择的读部分代码.在读代码之前,根据韦东山教材,关于代码学习内容和深度做以下预先划定. 一.Makefile.mkconfig.config.mk等 ...

  9. Linux 系统从入门到精通的学习大纲;

    以前没有接触过Linux,生产环境需要,有时候遇到问题,百度一下,问题解决了,在遇到问题,在百度,有时候问题是如何解决的,为什么会解决有点丈二的和尚摸不着头脑, 为此,想用一段时间,系统的学习下Lin ...

随机推荐

  1. nginx配置文件和一些用法

    fastcgi配置: location ~ \.php$ { #fastcgi_pass unix:///tmp/php-cgi.sock; fastcgi_pass unix__tmp_php5_c ...

  2. machine_learning-knn算法具体解释(近邻算法)

    近邻算法是机器学习算法中的入门算法,该算法用于针对已有数据集对未知数据进行分类. 该算法核心思想是通过计算预測数据与已有数据的相似度猜測结果. 举例: 如果有例如以下一组数据(在下面我们统一把该数据作 ...

  3. ocr 识别 github 源码

    参考 [1] https://github.com/eragonruan/text-detection-ctpn [2] https://github.com/senlinuc/caffe_ocr [ ...

  4. java开发常用到的jar包总结

    commons-io.jar: FileUtils 读取文件所有行 File file = new File("c:\\123.txt"); List<String> ...

  5. linux命令(6)crontab的用法和解析,修改编辑器

    注意: 如果不是vim打开的,可以先: crontab -e 命令将检查环境变量$ EDITOR和$ VISUAL以覆盖默认文本编辑器,所以... export VISUAL=vim or expor ...

  6. SAP ECC6安装系列五:安装后 License 的处理

    原作者博客 http://www.cnblogs.com/Michael_z/ ======================================== 我发现我确实比较懒,先和各位说声抱歉了 ...

  7. 基于jquery仿360网站图片选项卡切换代码

    今天给大家分享一款基于jquery仿360网站图片选项卡切换代码.这款实例适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预 ...

  8. 【基础练习】【区间DP】codevs2102 石子归并2(环形)题解

    题目描写叙述 Description 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次仅仅能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个 ...

  9. Centos 挂载NTFS格式的USB硬盘

    公司的一台服务器本身硬盘容量较小,要加一块2T的硬盘,用来做samba服务器,以下是挂载硬盘的主要记录: 这是服务器不认NTFS格式的情况:mount: unknown filesystem type ...

  10. groupBox和panel

    private void Form1_Load(object sender, EventArgs e) { groupBox1.Text = "信息表"; panel1.Borde ...