Objective c 单身汉被解约
我创建了一个简单的singleton类来保存项目的静态数据。 我第一次访问这个单例是在Cocos2d场景中的onEnter方法。然而,当我稍后在另一个方法(同一场景)中再次尝试访问它时,这个单例已经被释放。我很困惑,我该如何避免我的单身汉被解约 以下是我的singleton接口部分:Objective c 单身汉被解约,objective-c,ios,ios5,cocos2d-iphone,ios6,Objective C,Ios,Ios5,Cocos2d Iphone,Ios6,我创建了一个简单的singleton类来保存项目的静态数据。 我第一次访问这个单例是在Cocos2d场景中的onEnter方法。然而,当我稍后在另一个方法(同一场景)中再次尝试访问它时,这个单例已经被释放。我很困惑,我该如何避免我的单身汉被解约 以下是我的singleton接口部分: #import <Foundation/Foundation.h> @interface OrchestraData : NSObject +(OrchestraData *)sharedOrches
#import <Foundation/Foundation.h>
@interface OrchestraData : NSObject
+(OrchestraData *)sharedOrchestraData;
@property (retain, readonly) NSArray *animalNames;
@end
我是这样使用我的单身汉的:
[[OrchestraData sharedOrchestraData] animalNames];
更新:
我在启用NSZombies的情况下重新审视了它,它看起来好像我的NSArray被释放了,而不是singleton本身。我该怎么办?您可以在任何需要的地方设置指针
-(void)someMethod {
MySingleton *singleton = [MySingleton sharedSingleton];
singleton.data = YES; //dumb example to show you did something...
}
-(void)someOtherMethod {
MySingleton *singleton = [MySingleton sharedSingleton]; //You have to create a new pointer...
singleton.data = NO; //another dumber example to show you did something...
}
注意:这假设您已经创建了一个与我相同的单例。。。您的代码可能不同,因此导致我的答案不适用…您可以在任何需要的地方设置指针
-(void)someMethod {
MySingleton *singleton = [MySingleton sharedSingleton];
singleton.data = YES; //dumb example to show you did something...
}
-(void)someOtherMethod {
MySingleton *singleton = [MySingleton sharedSingleton]; //You have to create a new pointer...
singleton.data = NO; //another dumber example to show you did something...
}
注意:这假设您已经创建了一个与我相同的单例。。。您的代码可能不同,因此导致我的答案不适用…您必须以以下方式实现您的单例:
[[OrchestraData sharedOrchestraData] animalNames];
1) 在Singleton类的.h文件中:
+ (SingletonClass *)instance;
2) 在.m文件中:
+ (SingletonClass *)instance {
static SingletonClass* instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
//your init code here
});
return instance;
}
如果要调用singleton,只需调用[SingletonClass实例]
如果您对什么是“一次调度”感兴趣,请阅读有关Grand Central dispatch的内容:
您必须以以下方式实现您的单例:
[[OrchestraData sharedOrchestraData] animalNames];
1) 在Singleton类的.h文件中:
+ (SingletonClass *)instance;
2) 在.m文件中:
+ (SingletonClass *)instance {
static SingletonClass* instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
//your init code here
});
return instance;
}
如果要调用singleton,只需调用[SingletonClass实例]
如果您对什么是“一次调度”感兴趣,请阅读有关Grand Central dispatch的内容:
您需要在singleton类中覆盖下面的方法,因为在您的程序中,如果有人初始化了
[[SingletonClass alloc]init]
,那么singleton将有另一个实例,释放它将导致错误
+ (id)allocWithZone:(NSZone *)zone{
return [[self SingletonClass] retain];
}
- (id)copyWithZone:(NSZone *)zone{
return self;
}
- (id)retain{
return self;
}
您需要在singleton类中覆盖下面的方法,因为在您的程序中,如果有人初始化了
[[SingletonClass alloc]init]
,那么singleton将有另一个实例,释放它将导致错误
+ (id)allocWithZone:(NSZone *)zone{
return [[self SingletonClass] retain];
}
- (id)copyWithZone:(NSZone *)zone{
return self;
}
- (id)retain{
return self;
}
重新更新:
您的NSArray
解除分配,因为您使用的是autorelease初始值设定项arrayWithObjects
,并且您直接将其分配给ivaranimalNames\uuuz
。因此,它没有保留
要解决此问题,请将数组指定给属性:
self.animalNames = [NSArray arrayWithObjects:@"giraffe", @"giraffe", @"giraffe", @"giraffe", nil];
顺便说一句,根据ARC,这不会是一个问题,因为ivar将是一个强有力的(保留)参考。我不厌倦鼓励任何人切换到ARC。它已经使用了一年多了,再也没有必要使用MRC代码了!看到开发人员仍然没有使用更简单、更快、更直接的选项,我感到非常痛苦。(咆哮声关闭):)重新更新:
您的NSArray
解除分配,因为您使用的是autorelease初始值设定项arrayWithObjects
,并且您直接将其分配给ivaranimalNames\uuuz
。因此,它没有保留
要解决此问题,请将数组指定给属性:
self.animalNames = [NSArray arrayWithObjects:@"giraffe", @"giraffe", @"giraffe", @"giraffe", nil];
顺便说一句,根据ARC,这不会是一个问题,因为ivar将是一个强有力的(保留)参考。我不厌倦鼓励任何人切换到ARC。它已经使用了一年多了,再也没有必要使用MRC代码了!看到开发人员仍然没有使用更简单、更快、更直接的选项,我感到非常痛苦。(大声嚷嚷):)没有代码,如何帮助!:)说真的——发布一些代码。如何实现单例?如何访问singleton?很抱歉没有在前面发布代码。如果没有代码,如何帮助!:)说真的——发布一些代码。如何实现单例?如何访问单身汉?很抱歉没有提前发布代码。但并非所有单身汉都是一样的。请注意,
Class
对象已经是单例对象,因此,如果您想使所有内容都成为类方法,您可以这样做。更不用说ARC不会释放分配给静态
变量的内容,而正确编写的单例应该是这样的。不过,并非所有单例都是相同的。请注意,Class
对象已经是单例对象,因此,如果您想使所有内容都成为类方法,您可以这样做。更不用说ARC不会释放分配给静态
变量的内容,而正确编写的单例应该是。vai-vai-kitay有正确的答案。singleton应该维护一个指向自身的指针(在本例中为实例
),以避免释放;我建议将方法命名为sharedInstance
,并让它返回id
或instancetype
。如果您能告诉我这个实现与devmiles的代码有什么不同,那就太好了,因为我看不到它。从技术上讲,这两个代码示例是相同的,除非我忽略了什么(不过我仔细检查了)。顺便说一句,按照可可命名惯例,它应该被称为sharedOrchestraData。vai-vai-kitay有正确的答案。singleton应该维护一个指向自身的指针(在本例中为实例
),以避免释放;我建议将方法命名为sharedInstance
,并让它返回id
或instancetype
。如果您能告诉我这个实现与devmiles的代码有什么不同,那就太好了,因为我看不到它。从技术上讲,这两个代码示例是相同的,除非我忽略了什么(不过我仔细检查了)。顺便说一句,按照Cocoa命名约定,它应该被称为sharedOrchestraData。您不需要覆盖其中任何一个。您不需要覆盖其中任何一个。在这种特殊情况下,该属性是只读的。所以它不能这么容易使用。我建议在类扩展中将该属性重新定义为readwrite。您能解释一下使用self.animalNames与分配给animalNames_?@devmiles.com有什么不同吗?在这里没有找到答案。我认识赛尔夫·阿尼玛