Objective-C基础之面向对象编程(OOP)的基础知识(1)——间接

因为Cocoa是基于OOP概念的,并且Objective-C也是一种面向对象的编程语言,所以在学习Objective-C的时候必然频繁讨论OOP概念。


0x01 什么叫间接?


间接(Indirection)是一个OOP的关键概念,可以理解为“在代码中通过指针间接获取某个值,而不是直接获取”。



0x02 变量与间接


基本变量就是间接的一种实际应用,例如使用变量表示循环次数,如果想改变循环次数,只需修改代码中的变量值即可:

#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
  int count = 100;          //变量count起到间接的作用

  NSLog (@"The numbers from 1 to %d:", count);

  for (int i = 1; i <= count; i++) 
  NSLog (@"%d\n", i);

  return 0;
}


0x03 使用文件名的间接


在程序中内置的词组串列表

假设有一个程序可以统计并输出多个词组串的长度:

#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
  const char *words[4] = {
    "Joe-Bob \"Handyman\" Brown",
    "Jacksonville \"Sly\" Murphy",
    "Shinara Bain",
    "George \"Guitar\" Books" };      //词组串列表

  int wordCount = 4;                  //需统计的数目
 
  for (int i = 0; i < wordCount; i++) 
  NSLog (@"%s is %lu characters long", words[i], strlen(words[i]));

  return 0;
}

在这个程序中,如果我们经常要修改词组串列表,就必须频繁改动程序,还要同步修改需统计的数目变量。万一单词数目众多,我们就必须进行大量的修改工作,还得十分谨慎保证不犯错。从面向对象的角度来讲,这样是不科学的。


把词组串列表放入文本文件

所以,我们可以用另外一种思维构造程序:

将所有单词都移动到代码之外的某个文本文件中,按一定规则组织文件结构,如一行一个名字,这也是一种间接。

先构造一个文本文件(word.txt),并存放在tmp目录中:

Joe-Bob "Handyman" Brown
Jacksonville "Sly" Murphy
Shinara Bain
George "Guitar" Books


再构造一个程序读取该文本文件:

#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
  FILE *wordFile = fopen ("/tmp/words.txt", "r");          //tmp是Unix的临时目录,计算机重启时会被清空

  char word[100];
  while (fgets(word, 100, wordFile))
  {
  //把换行符替换成空字符
  word[strlen(word) - 1] = '\0';
  NSLog (@"%s is %lu characters long", word, strlen(word));
  }

  fclose (wordFile);

  return 0;
}

采用这种方案之后,我们可以在文本文件中随时改变词组串的组合,而不必修改程序,避免源代码遭到破坏。但是这个方案仍然不够便利,文件路径没法由使用者指定,万一文件不在程序指定的位置,我们同样必须修改源代码。


用命令行参数指定文件名

所以,我们要做进一步改进:

#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
  if (argc == 1)          //验证用户是否提供了路径名作为启动参数,argc的值至少为1,如果用户提供了路径名,则argc必然大于1
  {
  NSLog (@"you need to provide a file name");
  return 1;               // argc = 1时表示没有文件可读取
  } 

  //如果argc > 1,则按路径读取文件
  FILE *wordFile = fopen (argv[1], "r");

  char word[100];
  while (fgets(word, 100, wordFile))
  {
  //把换行符替换成空字符
  word[strlen(word) - 1] = '\0';
  NSLog (@"%s is %lu characters long", word, strlen(word));
  }

  fclose (wordFile);

  return 0;
}

其中,我们通过查看argv数组来获知词组串文件的路径。argv[0]存放着程序名,argv[1]保存着用户提供的文件名。


《C/C++语言体系中的main()函数参数argc, argv是什么?》


如果在终端应用中运行此程序,那么在命令行中指定文件名则如下所示:

$ ./Word-Length-4 /tmp/words.txt
Joe-Bob "Handyman" Brown is 24 characters long
Jacksonville "Sly" Murphy is 25 characters long
Shinara Bain is 12 characters long
George "Guitar" Books is 21 characters long


关于在调试运行前设置文件路径,请参考:

Xcode使用入门——在运行程序时提供文件路径


猜你喜欢

转载自blog.csdn.net/qq_33737036/article/details/76856045