- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先,请原谅这个问题的愚蠢,但我不是来自 C/C++ 背景。我有点不清楚 .h 和 .m 文件在属性方面的角色差异。
我理解接口(interface)的概念,并且我看到部分 .h 文件是实现的接口(interface),但我不清楚的是:
最佳答案
我将在下面回答您的问题,但也许学习这些东西的最好方法是阅读一些针对该语言新手的用户友好注释,例如 the Learn Objective-C tutorial在 cocoadevcentral .
一个例子
我想用一个例子来帮助回答你的问题(我喜欢通过例子学习)。假设您是一名教师,正在编写一个程序,该程序会询问学生一个特定的是/否问题,并跟踪有多少人答对了,以及有多少学生问了这个问题。
这是这个类的一个可能的接口(interface):
@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
是方法的声明(包括
@property
声明)。
retain
属性很有用,因为您想避免复制对象的开销,并确保在使用它时不会释放它。
retain
是合法的一个
NSString
就像在这个例子中一样,但是
it is often considered good practice to use copy
instead of retain
因为一个
NSString*
实际上可能指向一个
NSMutableString
对象,当你的代码希望它保持不变时,它可能会在以后改变。)
@property
@property
时,你在做两件事:
@property (nonatomic, retain) NSString* questionStr;
- (NSString*) questionStr; // getter
- (void) setQuestionStr: (NSString) newQuestionStr; // setter
nonatomic
等关键字给出的额外信息。和
retain
.
nonatomic
关键字表示它们不一定是线程安全的。常见的
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
@property
questionStr
的声明已
assign
相反,则所有
myQuestion.questionStr =
语句根本不会对保留计数进行任何更改。
IBOutlet
和 IBAction
做
IBOutlet
当编译器查看它时,字面上变成了一个空字符串,并且
IBAction
成为
void
返回值。不过,我们确实需要它们与 Interface Builder 一起工作,所以它们很重要——只是对编译器不重要。
->
引用结构的特定部分,如下所示:
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?"];
@private
来禁止其他人使用箭头符号。 ;如果你声明
@property
,他们仍然可以使用 getter 和 setter 来访问它。为了它。
@synthesize
说诸如“确保为该属性实现了 getter 和 setter。”它没有说“为我实现这两个”,因为编译器足够礼貌,会先检查您自己的实现,然后只填写您遗漏的部分。您不必使用
@synthesize
根本没有,即使你使用
@property
出 wazoo - 如果你喜欢那种事情,你总是可以为你的 setter 和 getter 提供你的实现。
Question
中注意到了上面的接口(interface)有一个不是实例变量的属性(
numWrongAnswers
),这很好,因为您只是在声明方法。在此处的示例代码中,您可以看到这实际上是如何工作的:
@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
numWrongAnswers
的实例变量。 ,如果我们将它存储在类中,这将是冗余信息。既然我们知道
numWrongAnswers
+
numCorrectAnswers
=
numTimesAsked
在任何时候,我们只需要存储这三个数据点中的任意两个,并且我们总是可以通过使用我们知道的两个值来考虑另一个。这里的重点是要理解
@property
声明实际上只是声明一个 setter 和 getter 方法,它们通常对应于一个实际的实例变量——但并非总是如此。
@synthesize
关键字默认对应一个实际的实例变量,所以编译器很容易为你填写实现。
.h
和 .m
文件
.h
头文件)中声明方法并在另一个文件(
.m
或方法文件)中定义它们的实现的重点是帮助解耦代码。例如,如果您只更新一个
.m
文件中,你不必重新编译另一个
.m
文件,因为它们的目标代码将保持不变——这可以节省时间。另一个优点是您可以使用仅包含头文件和预编译目标代码的库,甚至可以使用需要头文件的动态库,以便编译器知道存在哪些方法,但这些方法甚至没有链接到与您的可执行文件。当您第一次开始编码时,这些优势很难被理解,但只是实现的逻辑分解和封装在短时间内变得有用。
关于iphone - 与 Objective-C 中的头文件和实现文件混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1449698/
我遵循了一本名为“Sitepoint Full Stack Javascript with MEAN”的书中的教程,我刚刚完成了第 6 章,应该已经创建了一个带有“数据库”的“服务器”。数据库只不过是
在 Jquery 中,我创建两个数组,一个嵌入另一个数组,就像这样...... arrayOne = [{name:'a',value:1}, {name:'b',value:2}] var arra
这个问题在这里已经有了答案: What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wa
我被放在别人的代码上,有一个类用作其他组件的基础。当我尝试 ng serve --aot(或 build --prod)时,我得到以下信息。 @Component({ ...,
我正在测试一些代码,并使用数据创建了一个 json 文件。 问题是我在警报中收到“[object Object],[object Object]”。没有数据。 我做错了什么? 这是代码:
我想打印 [object Object],[object Object] 以明智地 "[[{ 'x': '1', 'y': '0' }, { 'x': '2', 'y': '1' }]]"; 在 ja
我有一个功能 View ,我正在尝试以特殊格式的方式输出。但我无法让列表功能正常工作。 我得到的唯一返回是[object Object][object Object] [object Object]
在使用优秀的 Sim.js 和 Three.js 库处理 WebGL 项目时,我偶然发现了下一个问题: 一路走来,它使用了 THREE.Ray 的下一个构造函数: var ray = new THRE
我正在使用 Material UI 进行多重选择。这是我的代码。 {listStates.map(col => (
我的代码使用ajax: $("#keyword").keyup(function() { var keyword = $("#keyword").val(); if (keyword.
我遇到了下一个错误,无法理解如何解决它。 Can't resolve all parameters for AuthenticationService: ([object Object], ?, [o
我正在尝试创建一个显示动态复选框的表单,至少应选中其中一个才能继续。我还需要获取一组选中的复选框。 这是组件的代码: import { Component, OnInit } from '@angul
我正在开发 NodeJs 应用程序,它是博客应用程序。我使用了快速验证器,我尝试在 UI 端使用快速闪存消息将帖子保存在数据库中之前使用闪存消息验证数据,我成功地将数据保存在数据库中,但在提交表单后消
我知道有些人问了同样的问题并得到了解答。我已经查看了所有这些,但仍然无法解决我的问题。我有一个 jquery snipet,它将值发送到处理程序,处理程序处理来自 JS 的值并将数据作为 JSON 数
我继承了一个非常草率的项目,我的任务是解释为什么它不好。我注意到他们在整个代码中都进行了这样的比较 (IQueryable).FirstOrDefault(x => x.Facility == fac
我只是在删除数组中的对象时偶然发现了这一点。 代码如下: friends = []; friends.push( { a: 'Nexus', b: 'Muffi
这两个代码片段有什么区别: object = nil; [object release] 对比 [object release]; object = nil; 哪个是最佳实践? 最佳答案 object
我应该为其他人将从中继承的第一个父对象传递哪个参数,哪个参数更有效 Object.create(Object.prototype) Object.create(Object) Object.creat
我在不同的对象上安排不同的选择器 [self performSelector:@selector(doSmth) withObject:objectA afterDelay:1]; [self per
NSLog(@"%p", &object); 和 NSLog(@"%p", object); 有什么区别? 两者似乎都打印出一个内存地址,但我不确定哪个是对象的实际内存地址。 最佳答案 这就是我喜欢的
我是一名优秀的程序员,十分优秀!