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. sim800L调试问题

    SIM800L默认上电开机,若此时没有把rst和pwk引脚提前设置好,SIM800l会使stm32进入硬件中断(这可能是因为方面电源的原因导致的),同时sim800L开机后需要一定的时间稳定下来,建议 ...

  2. C# 获取文件MD5、SHA1

    /// <summary> /// 计算文件的 MD5 值 /// </summary> /// <param name="fileName"> ...

  3. Django的ORM中如何判断查询结果是否为空,判断django中的orm为空

    result= Booking.objects.filter() #方法一 .exists() if result.exists(): print "QuerySet has Data&qu ...

  4. NTP Reply Flood Attack (NTP反射型DDos攻击)

    简介 NTP Reply Flood Attack (NTP射型Ddos攻击)以下简称NTP_Flood是一种利用网络中NTP服务器的脆弱性(无认证,不等价数据交换,UDP协议),来进行DDos行为的 ...

  5. Android_WebServices_源代码分析

    本博文为子墨原创,转载请注明出处! http://blog.csdn.net/zimo2013/article/details/38037989 在Android_WebServices_介绍一文中, ...

  6. Java Main如何被执行?

    java应用程序的启动在在/hotspot/src/share/tools/launcher/java.c的main()函数中,而在虚拟机初始化过程中,将创建并启动Java的Main线程.最后将调用J ...

  7. 检查是否是移动端(Mobile)、ipad、iphone、微信、QQ等

    <script type="text/javascript"> //判断访问终端 var browser={ versions:function(){ var u = ...

  8. vue 的调试工具

    转载自:http://www.cnblogs.com/lolDragon/p/6268345.html 安装 1.github下载地址:https://github.com/vuejs/vue-dev ...

  9. python学习笔记(2)--sublimeText3运行python

    https://www.zhihu.com/question/22904994 知乎用户 To the knowledge 74 人赞同 如果是想在sublime里要python shell那种交互或 ...

  10. 一款基于jQuery的图片下滑切换焦点图插件

    之前为大家分享了好多款jquery插件,今天我们要分享的一款jQuery插件也比较实用,是一款jQuery焦点图插件.焦点图相当普通,一共可以循环播放4张图片,并且每一张图片在切换的时候都是向下滑动的 ...