Objective c 在obj-c中用单例存储实例引用
假设我有两个班,A和B。A是单身。我在B中声明了A,所以我可以访问B中方法中的单例变量 B然后创建另一个类的实例,比如C类 然后C创建另一个类的实例,比如说类D 我需要做的是在类D中的类B的实例中运行一个方法,这就是让我发疯的原因 我的第一个想法是在我的单例(类a)中引用类b的实例,类似于Objective c 在obj-c中用单例存储实例引用,objective-c,ios,Objective C,Ios,假设我有两个班,A和B。A是单身。我在B中声明了A,所以我可以访问B中方法中的单例变量 B然后创建另一个类的实例,比如C类 然后C创建另一个类的实例,比如说类D 我需要做的是在类D中的类B的实例中运行一个方法,这就是让我发疯的原因 我的第一个想法是在我的单例(类a)中引用类b的实例,类似于 sharedInstance.classBReference = self; …然后在类D中声明单例,然后在类D实例中使用类似的内容 [sharedInstance.classBInstance class
sharedInstance.classBReference = self;
…然后在类D中声明单例,然后在类D实例中使用类似的内容
[sharedInstance.classBInstance classBInstanceMethod];
当然,只要我这么做了
classB *classBReference;
在我的单件游戏的标题中,它给了我一个“未知类型”的游戏,我在这里读到了关于它的内容,因此,我把一个
@class classB;
在@接口上方,然后我可以声明
classB *classBReference;
没有未知类型的错误,但在类B的init方法中,此
sharedInstance.classBReference = self;
仍然给我一个类型错误
在类型为“class A*”(单例)的对象上未找到属性ClassBreeference。您是要访问ivar ClassBreeference吗
我不知道它为什么这么做,解决办法是什么?还是有更好的方法来完成我想做的事情?错误消息会告诉您答案。您应该将
classbreeference
定义为属性,或者使用classbreeference
作为ivar。避免使用全局变量(也称为singleton)听起来会比较容易混淆。当B
创建C
时,为C
提供对B
的引用。当C
创建D
时,为D
提供对B
的引用
如果您需要避免保留周期,请反向引用B
(如果您的部署目标至少为iOS 5.0)或不安全(如果您的部署目标早于iOS 5.0)。点和箭头
“点表示法”是Objective-C最近增加的一种表示法,它为访问者提供了一种简写表示法。如果有指向对象(或结构!)的指针,则不能使用
访问其实例变量,而只能使用->
你的线路
sharedInstance.classBReference = self;
完全一样
[sharedInstance setClassBReference:self];
问题是您没有任何这样的方法-setClassBreeference:
。为了设置实例变量,必须改为编写
sharedInstance->classBReference = self;
@保护变量
用这一行切换后,您可能(如果您没有将其设置为公共的话)会看到错误
实例变量“classbreeference
”是私有的
在这种情况下,您需要更改classA
接口,以便将classbreeference
声明为@public
。classA
中的实例变量列表应该如下所示
@interface classA : NSObject
{
//@protected
//(The @protected keyword is optional when at the beginning of the list; instance
//variables are protected by default, which is why you're needing to declare your
//instance variable classBReference to be @public (since classB is not a subclass
//of classA and consequently cannot access its protected instance variables).
//....
//some protected instance variables
//....
@private
//....
//some private instance variables
//....
@public
//....
//some public instance variables
classB *classBReference;
//....
@protected
//....
//some more protected instance variables
//Note that @protected is not optional in order to make the instance variables
//here be protected since they are declared subsequent to the prior @public.
//....
}
//....
@end
使用@properties
类引用案例
也就是说,一般认为使用访问器比使用实例变量更好。为此,您应该向classA
接口添加一个属性:
@interface classA : NSObject
{
classB *classBReference;
}
@property classB *classBReference;
@end
并合成classbreeference
属性,以访问classA
实现中的classbreeference
实例变量,如下所示:
@implementation classB
@synthesize classBReference = classBReference;
总体结构
@synthesis
有点不清楚,因为我们有一个实例变量和一个同名的属性。需要作出一些澄清。通常,在类的(“MyObject
”在本例中)@接口
中声明一个实例变量(myVariable
”)和一个属性(myProperty
”)
在类的@实现中
有一行
@synthesize myProperty = myVariable.
该代码的结果是,给定一个实例
MyObject *object = //...
在班上,一个人会写字
SomeObject *someObject = //...
[object setMyProperty:someObject];
object.myProperty = someObject;
SomeObject *someOtherObject = object.myProperty;
及
对MyObject
实例调用-setMyProperty:
的结果是myVariable
设置为等于传递给方法的参数——在本例中为someObject
。类似地,对MyObject
的实例调用-myProperty
的结果是返回myVariable
它给我们带来了什么?
如果没有@property
和@synthesis
指令,就必须声明方法
- (void)setMyProperty:(SomeObject *)myProperty;
- (SomeObject *)myProperty;
手动并手动定义它们:
- (void)setMyProperty:(SomeObject *)myProperty
{
myVariable = myProperty;
}
- (SomeObject *)myProperty
{
return myVariable;
}
@属性
和@synthesis
对该代码进行了一些删节。当您使用各种不同的方法时,为您生成的代码量会变得更加有用
注意:关于@属性
和@合成
指令。首先,你不仅可以编写@synthesis-myProperty
省略变量名,您可以完全省略合成myProperty
,并且在这两种情况下自动使用的变量名彼此不同
关于点符号的更多信息
问题中的点符号提供了另一层缩写。而不是必须写作
[object setMyProperty:someObject];
SomeObject *someOtherObject = [object myProperty];
你现在可以写作了
SomeObject *someObject = //...
[object setMyProperty:someObject];
object.myProperty = someObject;
SomeObject *someOtherObject = object.myProperty;
同样地,也不必写
[object setMyProperty:someObject];
SomeObject *someOtherObject = [object myProperty];
你现在可以写作了
SomeObject *someObject = //...
[object setMyProperty:someObject];
object.myProperty = someObject;
SomeObject *someOtherObject = object.myProperty;
需要注意的是,这只是符号。虽然当我们“将object.myProperty
设置为someObject
”时,它“看起来有点像”我们在做简单的赋值,但事实并非如此。特别是,当我们执行该行时
object.myProperty = someObject;
方法
- (void)setMyProperty:(SomeObject *)someObject
被执行。因此。这是一种方便,但重要的是要记住您的代码正在做什么