Objective c 将实例变量放在.h中它不会';i don’我没有一个能手和能手(也就是说,没有人能设置或获得它)?

Objective c 将实例变量放在.h中它不会';i don’我没有一个能手和能手(也就是说,没有人能设置或获得它)?,objective-c,interface,sqlite,singleton,instance-variables,Objective C,Interface,Sqlite,Singleton,Instance Variables,我已经读了一些书和其他问题,但我仍然感到困惑 我正在阅读SQLite教程: h 请纠正我的错误: sqlite3*数据库: 这不是财产吗 没有任何证据 在.m文件中没有任何setter或getter,因此没有其他类可以访问它——这违背了将其放入.h文件的目的 所有这些都意味着我们无法访问或设置它我们为什么要这样做? 将其放入.h文件的目的是什么;为什么不 作为属性写入还是只写我们的.m文件? 编辑: 在Objective-C中使用Sqlite3的现代方式是什么?你说得有点对,Sqlite3*

我已经读了一些书和其他问题,但我仍然感到困惑

我正在阅读SQLite教程:

h

请纠正我的错误:
sqlite3*数据库

  • 这不是财产吗
  • 没有任何证据
  • 在.m文件中没有任何setter或getter,因此没有其他类可以访问它——这违背了将其放入
    .h
    文件的目的
所有这些都意味着我们无法访问或设置它我们为什么要这样做?

将其放入
.h
文件的目的是什么;为什么不 作为属性写入
还是只写我们的
.m
文件?

编辑:
在Objective-C中使用Sqlite3的现代方式是什么?

你说得有点对,
Sqlite3*\u数据库
不是一个属性,没有合成的setter或getter,但你可以通过直接引用来访问它。如果它在标题中,它将被公开声明,因此任何拥有
FailedBankDatabase
实例的人都可以直接访问
\u数据库的内存位置并与之交互。这根本不需要一个能干的人去做

因此,使用性能更好。通过让客户通过getter,您可以更好地控制访问


静态故障银行数据库*\u数据库
是一个名称相同但完全不相关的变量。它是静态的,因此它有类作用域,访问
\u数据库的方法的作用域决定了访问哪个变量。这是一种混乱且糟糕的形式…

实现
块中声明实例变量并不总是可能的。这已经有可能好几年了,但该教程的日期是2010年4月8日。在编写它时,作者可能希望它能在较旧版本的编译器上工作

由于
\u database
未声明为
@private
,因此实际上可以在
FailedBankDatabase
实现之外访问实例变量。在Objective-C中,可以将对象指针视为结构指针,并访问其实例变量,如结构字段。所以你可以这样做:

#import "FailedBankDatabase.h"

int main(int argc, char *argv[])
{
    FailedBankDatabase *db = [FailedBankDatabase database];
    printf("instance variable: %p\n", db->_database);
    return 0;
}
不过,这可能是个坏主意

使现代化 由于您的
sqlite3*\u数据库是专用的,因此您可能只想执行以下操作:

FailedBankDatabase.h

为什么有一个名为
\u database
的实例变量和一个名为
\u database
的全局变量?这不可能是对的。它确实令人困惑,而且形式糟糕,特别是对于教程…@trojanfoe什么是非常有用的?那么正确的方法是什么呢?如果实例变量不在那里,该怎么办?你会在.h中写一个实例变量而不为它写一个getter和setter吗?@asma22,但这个例子特别糟糕。查看我的答案。了解如何从另一个类访问用.h编写的IVAR,请参阅答案;您必须使用
->
访问对象/实例的变量
obj->var
我很困惑!直接引用是什么意思?我可以说
FailedBankDatabase.\u数据库
类似于如果它是一个属性,我会做什么?如果它不使用getter调用,那么它调用什么!?不,因为这是一个类,所以您可以在实例中直接引用(但您通常不想这样做)。非常感谢!哦,是的,我的意思是直接引用一个实例。那么在.h中使用ivar是否有任何用例——如果您看到我们通常不想这样做的话。IVAR的默认值是什么?它们和原子的、强的、读写的一样吗?没有一个好的用例,都是作弊。没有关于访问的规范。这就是属性存在的原因…你能用属性折射它吗?对于像我这样的新手来说:因为当我们处理类的实例时,我们使用的是一个指向对象(特殊结构)的指针。因此,我们使用
->
访问公共字段。如果它是一个属性,我们可以使用点符号来访问它。现代Objective-C是如何实现的?我应该把sqlite3作为我的财产吗?请您编辑您的答案,以包括现代的方式这样做吗?罗伯,谢谢你的更新。您是否刚刚添加了
,以确保该类型数组中的所有对象都是正确的?我们不需要使用dispatch_一次,这样我们就可以保护自己不受比赛条件的影响吗?i、 e.避免创建共享实例的两个实例?是的,为了更好地进行类型检查,我添加了这一点。如果要允许从多个线程使用
FailedBankDatabase
,则只需添加
dispatch\u一次
,但可能还需要在许多其他位置使用锁。
#import "FailedBankDatabase.h"
#import "FailedBankInfo.h"

@implementation FailedBankDatabase

static FailedBankDatabase *_database;

+ (FailedBankDatabase*)database {
    if (_database == nil) {
        _database = [[FailedBankDatabase alloc] init];
    }
    return _database;
}
#import "FailedBankDatabase.h"

int main(int argc, char *argv[])
{
    FailedBankDatabase *db = [FailedBankDatabase database];
    printf("instance variable: %p\n", db->_database);
    return 0;
}
#import <Foundation/Foundation.h>

@class FailedBankInfo;

@interface FailedBankDatabase : NSObject

+ (FailedBankDatabase*)database;
- (NSArray<FailedBankInfo *> *)failedBankInfos;

@end
#import "FailedBankDatabase.h"
#import "FailedBankInfo.h"
#import <sqlite3.h>

@implementation FailedBankDatabase {
    sqlite3 *_database;
}

static FailedBankDatabase *theInstance;

+ (FailedBankDatabase*)database {
    if (theInstance == nil) {
        theInstance = [[FailedBankDatabase alloc] init];
    }
    return theInstance;
}