Objective C – 示例Singleton实现

* 我绝对需要rest…原因很简单 – 数组未分配…感谢您的帮助。 由于这个尴尬的错误,我标记我的post,以删除它。 我不觉得它对用户有用;)*

我刚刚尝试在iOS中创build一个单例类,但我可能犯了一个错误。 代码(不需要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中的值相同。

创build单身人士的标准方式就像…

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 
  @synchronized(self) { if (instance == nil) NSLog(@"initializing"); instance = [[[self alloc] init] retain]; NSLog(@"Address: %p", instance); } 

你似乎错过了你的括号, if声明。 正如所写的,只有当instance == nil时,你做的唯一的事情就是发出一条日志消息。

这是一个可以避免的一些错误,通常使用大括号后跟if和else。

 +(PeopleDatabase *)getInstance { @synchronized(self) { if (instance == nil) NSLog(@"initializing"); instance = [[[self alloc] init] retain]; NSLog(@"Address: %p", instance); } return(instance); } 

如果实例是零,那么下一个语句,只有执行。 这是nslog而不是分配。 然后分配实例,不pipe之前是否使用实例。 这将在每次通话中为您提供一个新的单身人士。 顺便说一句,造成泄漏。

 +(PeopleDatabase *)getInstance { @synchronized(self) { if (instance == nil) { NSLog(@"initializing"); instance = [[[self alloc] init] retain]; NSLog(@"Address: %p", instance); } } return(instance); } 

但是这个错误在debugging的时候出现了。 它可能会让你困惑,但并不能解决你原来的问题。 请添加一个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是零,addObject被发送到零,这不会导致中止,但也不会做任何事情。 然后计数被发送到零至零返回0 /零。

在这个函数+(PeopleDatabase *)getInstance我想你需要正确地放置大括号:像这样

 +(PeopleDatabase *)getInstance { @synchronized(self) { if (instance == nil) { NSLog(@"initializing"); instance = [[[self alloc] init] retain]; NSLog(@"Address: %p", instance); } return instance ; } } 

在网页阅读和个人练习之后,我现在的单例实现是:

 @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; } 

这是一个线程安全的实现,并通过在你的类上调用“alloc init”来避免创build新对象的风险。 属性初始化必须发生在块内部,而不是出于类似原因的“init”覆盖。