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
检查这个苹果文档如何创build单例实例:
@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”覆盖。