Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 与Objective-C中的头文件和实现文件混淆_Iphone_Objective C_Properties - Fatal编程技术网

Iphone 与Objective-C中的头文件和实现文件混淆

Iphone 与Objective-C中的头文件和实现文件混淆,iphone,objective-c,properties,Iphone,Objective C,Properties,首先,请原谅这个问题的愚蠢,但我不是C/C++背景。对于.h和.m文件在属性方面的角色差异,我有点不清楚 我理解接口的概念,我看到.h文件在某种程度上是实现的接口,但我不清楚的是: 为什么在{}大括号之外定义属性/方法 当我写这样的东西时,我在大括号中定义了什么: IBUITextField*数字字段 这是接口中的字段定义吗 当我将@Property行添加到.h文件时,这些是n auto属性的实际实现还是仅仅是一个接口蓝图?如果是的话,@syntesis是实际的实现吗 我想我最大的困惑似乎是

首先,请原谅这个问题的愚蠢,但我不是C/C++背景。对于.h和.m文件在属性方面的角色差异,我有点不清楚

我理解接口的概念,我看到.h文件在某种程度上是实现的接口,但我不清楚的是:

  • 为什么在{}大括号之外定义属性/方法
  • 当我写这样的东西时,我在大括号中定义了什么:

    IBUITextField*数字字段

    这是接口中的字段定义吗

  • 当我将@Property行添加到.h文件时,这些是n auto属性的实际实现还是仅仅是一个接口蓝图?如果是的话,@syntesis是实际的实现吗

我想我最大的困惑似乎是,如果我想要一个属性,我将在三个不同的地方定义我需要的东西(1)在大括号中,(2)在大括号外定义为@property,(3)在.m文件中定义为@synthesis。这似乎很冗长,但如果我能弄清楚这三个部分的作用,那就好了

干杯,克里斯

  • 方法是在大括号之外定义的,因为大括号旨在封装对象的状态,而对象的状态不包括实例或类方法

  • 大括号中定义的是可以作为self.ivar引用的实例变量

  • @property和@synthesis指令只是为您的实例变量设置访问器,以便您可以通过执行self.ivar=someVar来设置它们。换句话说,它设置了“点语法”供您使用

  • 回答最后一个问题:要定义属性或实例变量,只需在.h文件中将其声明为大括号内的变量。要在同一属性上设置访问器方法,您需要同时执行@property和@synthesis

  • 这就是目标C语法,{}外的方法和@property,{}内的变量

  • @属性是告诉您将要编写getter和setter(某种程度上强制执行)的方式,但是您可以编写getter/setter而无需将它们设置为@property@属性位于.h文件中,因为它的声明。为什么它在{}之外,就像我之前说的,只是语法,我们能做什么

  • @合成将在实际中实现getter和setter,如果您不进行合成,但已将它们设置为@property,则必须手动实现这些getter和setter。而@synthesis位于.m文件中,因为它的实现

  • 你可以在这里找到更多关于这个主题的内容


    我将回答您下面的问题,但学习这门语言的最好方法可能是阅读一些面向新手的用户友好的笔记,例如在

    示例

    我想用一个例子来回答你的问题(我喜欢通过例子学习)。假设您是一名教师,编写了一个程序,向学生询问一个特定的是/否问题,并记录有多少学生正确回答了该问题,以及有多少学生回答了该问题

    下面是该类的一个可能接口:

    @interface Question : NSObject {
      NSString* questionStr;
      int numTimesAsked;
      int numCorrectAnswers;
    }
    
    @property (nonatomic, retain) NSString* questionStr;
    @property (nonatomic, readonly) int numTimesAsked;
    @property (nonatomic) int numCorrectAnswers;
    @property (nonatomic) int numWrongAnswers;
    
    - addAnswerWithTruthValue: (BOOL) isCorrect;
    @end
    
    大括号中的三个变量是实例变量,类的每个实例都有自己的值。大括号之外但
    @end
    之前的所有内容都是方法声明(包括
    @属性声明)

    (旁注:对于许多对象,拥有
    retain
    属性非常有用,因为您希望避免复制对象的开销,并确保在使用对象时不会释放该对象。在本例中,保留
    NSString
    是合法的,但因为
    NSString*
    实际上可能指向
    NSMutableString
    对象,当代码希望它保持不变时,它可能会在以后更改。)

    什么是
    @property

    当您声明一个
    @属性时,您正在做两件事:

  • 在类的接口中声明setter和getter方法,以及
  • 指示setter和getter的行为方式
  • 对于第一个问题,知道这一行就足够了:

    @property (nonatomic, retain) NSString* questionStr;
    
    与此基本相同:

    - (NSString*) questionStr;                           // getter
    - (void) setQuestionStr: (NSString) newQuestionStr;  // setter
    
    您实际上是在声明这两个方法;您可以直接调用它们,或者使用点符号作为快捷方式来调用它们

    “基本相同”中的“基本相同”部分是由
    非原子
    保留
    等关键字提供的额外信息

    nonatomic
    关键字表示它们不一定是线程安全的。common
    retain
    关键字表示对象保留已设置的任何值,并在释放之前的值时释放它们

    例如:

    // The correct answer to both questions is objectively YES.
    Question* myQuestion = [[Question alloc] init];
    NSString* question1 = [[NSString alloc] initWithString:@"Is pizza tasty?"];
    // question1 has retain count of 1, from the call to alloc
    myQuestion.questionStr = question1;
    // question1 now has a retain count of 2
    NSString* question2 = [[NSString alloc] initWithString:@"Free iPhone?"];
    myQuestion.questionStr = question2;
    // question1 has a retain count of 1, and question2 has retain count of 2
    
    如果
    questionStr
    @property
    声明改为
    assign
    ,则所有
    myquestionstr=
    语句都不会对保留计数进行任何更改

    你可以

    IBOutlet
    和IBAction
    做什么

    这些基本上没有运算词,它们只是告诉接口生成器要注意头文件的哪些部分。当编译器查看时,
    IBOutlet
    实际上变成了一个空字符串,
    IBAction
    变成了
    void
    返回值。我们确实需要它们来与接口生成器一起工作gh,所以它们很重要——只是对编译器来说不重要

    关于C结构和箭头与点符号的快速说明

    顺便说一下,Objective-C对象的数据部分与C结构非常相似。如果有指向C结构的指针,可以使用箭头符号
    ->
    来引用结构的特定部分,如
    struct MyStructType {
      int i;
      BOOL b;
    };
    struct MyStructType* myStruct;
    myStruct->i = 3;
    myStruct->b = TRUE;  // or YES in Objective-C.
    
    Question* question = [[Question alloc] init];
    question->questionStr = @"Is this a long answer?";  // YES
    
    question.questionStr = @"Chocolate?";
    [question setQuestionStr:@"Chocolate?"];
    
    @implementation Question
    
    @synthesize questionStr, numTimesAsked, numCorrectAnswers;
    
    - (void) setNumCorrectAnswers: (int) newCorrectAnswers {
      // We assume the # increases, and represents new answers.
      int numNew = newCorrectAnswers - numCorrectAnswers;
      numTimesAsked += numNew;
      numCorrectAnswers = newCorrectAnswers;
    }
    
    - (int) numWrongAnswers {
      return numTimesAsked - numCorrectAnswers;
    }
    
    - (void) setNumWrongAnswers: (int) newWrongAnswers {
      int numNew = newWrongAnswers - self.numWrongAnswers;
      numTimesAsked += numNew;
    }
    
    - (void) addAnswerWithTruthValue: (BOOL) isCorrect {
      if (isCorrect) {
        self.numCorrectAnswers++;
      } else {
        self.numWrongAnswers++;
      }
    }
    
    @end