* 我肯定需要休息一下......原因很简单 - 数组没有分配...感谢您的帮助。由于这个令人尴尬的错误,我标记了我的帖子以删除它。我觉得它对用户没用;)*
我刚尝试在iOS中创建一个单例类,但我可能犯了一个错误。代码(无需ARC):
#import "PeopleDatabase.h"
#import "Person.h"
#import <Foundation/Foundation.h>
@interface PeopleDatabase : NSObject{objetive
NSMutableArray* _arrayOfPeople;
}
+(PeopleDatabase *) getInstance;
@property (nonatomic, retain) NSMutableArray* arrayOfPeople;
@end
-
@implementation PeopleDatabase
@synthesize arrayOfPeople = _arrayOfPeople;
static PeopleDatabase* instance = nil;
-(id)init{
if(self = [super init]) {
Person* person = [[[Person alloc] initWithName:@"John" sname:@"Derovsky" descr:@"Some kind of description" iconName:@"johnphoto.png" title:Prof] retain];
[_arrayOfPeople addObject:person];
NSLog(@"array count = %d", [_arrayOfPeople count]); // <== array count = 0
[person release];
}
return self;
}
+(PeopleDatabase *)getInstance {
@synchronized(self)
{
if (instance == nil)
NSLog(@"initializing");
instance = [[[self alloc] init] retain];
NSLog(@"Address: %p", instance);
}
return(instance);
}
-(void)dealloc {
[instance release];
[super dealloc];
}
@end
像这里一样调用getInstance:
PeopleDatabase *database = [PeopleDatabase getInstance];
NSLog(@"Adress 2: %p", database);
地址2的值与getInstance中的值相同。
答案 0 :(得分:23)
创建单身的标准方法就像......
Singleton.h
@interface MySingleton : NSObject
+ (MySingleton*)sharedInstance;
@end
Singleton.m
#import "MySingleton.h"
@implementation MySingleton
#pragma mark - singleton method
+ (MySingleton*)sharedInstance
{
static dispatch_once_t predicate = 0;
__strong static id sharedObject = nil;
//static id sharedObject = nil; //if you're not using ARC
dispatch_once(&predicate, ^{
sharedObject = [[self alloc] init];
//sharedObject = [[[self alloc] init] retain]; // if you're not using ARC
});
return sharedObject;
}
@end
答案 1 :(得分:2)
检查此Apple doc如何创建单例实例:
答案 2 :(得分:2)
@synchronized(self)
{
if (instance == nil)
NSLog(@"initializing");
instance = [[[self alloc] init] retain];
NSLog(@"Address: %p", instance);
}
您似乎错过了if
声明的大括号。如上所述,当instance == nil
发出日志消息时,您唯一做的就是不同。
答案 3 :(得分:1)
在网络阅读和个人练习之后,我目前的单身实施是:
@interface MySingleton
@property myProperty;
+(instancetype) sharedInstance;
@end
@implementation MySingleton
+ (instancetype) sharedInstance
{
static dispatch_once_t pred= 0;
__strong static MySingleton *singletonObj = nil;
dispatch_once (&pred, ^{
singletonObj = [[super allocWithZone:NULL]init];
singletonObj.myProperty = initialize ;
});
return singletonObj;
}
+(id) allocWithZone:(NSZone *)zone
{
return [self sharedInstance];
}
-(id)copyWithZone:(NSZone *)zone
{
return self;
}
这是一个线程安全的实现,通过调用&#34; alloc init&#34;来避免创建新对象的风险。在你的班上属性初始化必须在块内部进行,而不是在&#34; init&#34;内部进行。因类似原因而改写。
答案 4 :(得分:0)
在这个函数中+(PeopleDatabase *)getInstance
我认为你需要正确放置花括号:像这样
+(PeopleDatabase *)getInstance {
@synchronized(self)
{
if (instance == nil)
{
NSLog(@"initializing");
instance = [[[self alloc] init] retain];
NSLog(@"Address: %p", instance);
}
return instance ;
}
}
答案 5 :(得分:0)
这是一个错误,可以通过一些解压缩的约定来避免,它总是使用大括号后跟if和else。
+(PeopleDatabase *)getInstance {
@synchronized(self)
{
if (instance == nil)
NSLog(@"initializing");
instance = [[[self alloc] init] retain];
NSLog(@"Address: %p", instance);
}
return(instance);
}
如果instance为nil则为下一个语句,只执行该语句。这就是nslog而不是分配。然后无论如何都要分配实例,无论之前是否使用过。这将为您在每次通话时提供新的单身人士。 BTW导致泄漏。
+(PeopleDatabase *)getInstance {
@synchronized(self)
{
if (instance == nil) {
NSLog(@"initializing");
instance = [[[self alloc] init] retain];
NSLog(@"Address: %p", instance);
}
}
return(instance);
}
但是这个错误在调试时出现了。它可能会让您感到困惑,但无法解决原始问题。请添加一个alloc和init,并保留_arrayOfPeople
。
-(id)init{
if(self = [super init]) {
Person* person = [[[Person alloc] initWithName:@"John" sname:@"Derovsky" descr:@"Some kind of description" iconName:@"johnphoto.png" title:Prof] retain];
_arrayOfPeople = [[[NSMutableArray alloc] init] retain]; //dont forget the release
[_arrayOfPeople addObject:person];
NSLog(@"array count = %d", [_arrayOfPeople count]); // <== array count = 1 !!!
[person release];
}
return self;
}
在你的代码中,_arrayOfPeople为nil,addObject被发送到nil,这不会导致中止但也不会执行任何操作。然后将count发送到nil,返回0 / nil。