1、 单例模式的概念
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
2、书写步骤
- 创建类方法,返回对象实例.以shared default current开头。
- 创建一个全局变量用来保存对象的引用
- 判断对象是否存在,若不存在,创建对象
3、具体单例模式的几种模式
- 第一种单例模式
1 非线程安全写法 2 3 static UserHelper * helper = nil; 4 5 + (UserHelper *)sharedUserHelper { 6 7 if (helper == nil) { 8 9 helper = [[UserHelper alloc] init]; 10 11 } 12 13 return helper; 14 15 }
- 第二种单例模式
1 线程安全写法1 2 3 4 5 static UserHelper * helper = nil; 6 7 + (UserHelper *)sharedUserHelper { 8 9 @synchronized(self) { 10 11 12 13 if (helper == nil) { 14 15 helper = [[UserHelper alloc] init]; 16 17 } 18 19 } 20 21 return helper; 22 23 }
- 第三种单例模式
1 + (void)initialize { 2 3 4 5 if ([self class] == [UserHelper class]) { 6 7 helper = [[UserHelper alloc] init]; 8 9 } 10 11 }
- 第四种单例模式
1 线程安全写法3(苹果推荐,主要用这个) 2 3 static UserHelper * helper = nil; 4 5 + (UserHelper *)sharedUserHelper { 6 7 8 9 static dispatch_once_t onceToken; 10 11 dispatch_once(&onceToken, ^{ 12 13 helper = [[UserHelper alloc] init]; 14 15 }); 16 17 18 19 return helper; 20 21 }
1 MRC全面实现单例写法(了解) 2 3 4 5 #import <Foundation/Foundation.h> 6 7 #import "UserHelper.h" 8 9 10 11 void func() { 12 13 14 15 static dispatch_once_t onceToken; 16 17 dispatch_once(&onceToken, ^{ 18 19 NSLog(@"haha"); 20 21 }); 22 23 } 24 25 26 27 int main(int argc, const char * argv[]) { 28 29 @autoreleasepool { 30 31 32 33 // [UserHelper logout]; 34 35 36 37 if ([UserHelper isLogin]) { 38 39 40 41 UserHelper * helper = [UserHelper sharedUserHelper]; 42 43 NSLog(@"username = %@ password = %@",helper.userName,helper.password); 44 45 46 47 } else { 48 49 50 51 char name[20]; 52 53 char pwd[20]; 54 55 NSLog(@"请输入用户名"); 56 57 scanf("%s",name); 58 59 NSLog(@"请输入密码"); 60 61 scanf("%s",pwd); 62 63 64 65 NSString * userName = [[NSString alloc] initWithUTF8String:name]; 66 67 NSString * password = [[NSString alloc] initWithUTF8String:pwd]; 68 69 70 71 if (userName && password) { 72 73 74 75 [UserHelper loginWithUserName:userName password:password]; 76 77 78 79 UserHelper * helper = [UserHelper sharedUserHelper]; 80 81 NSLog(@"username = %@ password = %@",helper.userName,helper.password); 82 83 84 85 } 86 87 } 88 89 90 91 // UserHelper * help1 = [UserHelper sharedUserHelper]; 92 93 // help1.userName = @"dahuan"; 94 95 // help1.password = @"123456"; 96 97 // NSLog(@"%p",help1); 98 99 // NSLog(@"%@",help1.userName); 100 101 // NSLog(@"%@",help1.password); 102 103 // 104 105 // 106 107 // UserHelper * help2 = [UserHelper sharedUserHelper]; 108 109 // help2.password = @"zxc"; 110 111 // NSLog(@"%p",help2); 112 113 // NSLog(@"%@",help1.userName); 114 115 // NSLog(@"%@",help1.password); 116 117 118 119 } 120 121 return 0; 122 123 } 124 125 //class.h 126 127 #import <Foundation/Foundation.h> 128 129 130 131 @interface UserHelper : NSObject 132 133 134 135 //1、创建类方法,返回对象实例 shared default current 136 137 138 139 + (UserHelper *)sharedUserHelper; 140 141 142 143 @property (nonatomic, copy) NSString * userName; 144 145 146 147 @property (nonatomic, copy) NSString * password; 148 149 150 151 + (BOOL)isLogin; 152 153 154 155 + (void)loginWithUserName:(NSString *)userName password:(NSString *)password; 156 157 158 159 + (void)logout; 160 161 162 163 @end 164 165 166 167 // class.m 168 169 #import "UserHelper.h" 170 171 172 173 //2、创建一个全局变量 174 175 176 177 #define Path @"/Users/dahuan/Desktop/data" 178 179 180 181 static UserHelper * helper = nil; 182 183 184 185 @implementation UserHelper 186 187 188 189 //+ (void)initialize { 190 191 // 192 193 // if ([self class] == [UserHelper class]) { 194 195 // helper = [[UserHelper alloc] init]; 196 197 // } 198 199 //} 200 201 202 203 + (UserHelper *)sharedUserHelper { 204 205 206 207 //3、判断对象是否存在,若不存在,创建对象 208 209 //线程安全 210 211 // @synchronized(self) { 212 213 // 214 215 // if (helper == nil) { 216 217 // helper = [[UserHelper alloc] init]; 218 219 // } 220 221 // } 222 223 224 225 //gcd 线程安全 226 227 static dispatch_once_t onceToken; 228 229 dispatch_once(&onceToken, ^{ 230 231 helper = [[UserHelper alloc] init]; 232 233 }); 234 235 236 237 return helper; 238 239 } 240 241 242 243 - (instancetype)init { 244 245 246 247 if (self = [super init]) { 248 249 250 251 NSString * data = [NSString stringWithContentsOfFile:Path encoding:NSUTF8StringEncoding error:nil]; 252 253 if (data) { 254 255 NSArray * array = [data componentsSeparatedByString:@"-"]; 256 257 _userName = array[0]; 258 259 _password = array[1]; 260 261 } 262 263 } 264 265 return self; 266 267 } 268 269 270 271 + (BOOL)isLogin { 272 273 274 275 UserHelper * helper = [UserHelper sharedUserHelper]; 276 277 if (helper.userName && helper.password) { 278 279 return YES; 280 281 } 282 283 return NO; 284 285 } 286 287 288 289 + (void)loginWithUserName:(NSString *)userName password:(NSString *)password { 290 291 292 293 UserHelper * helper = [UserHelper sharedUserHelper]; 294 295 helper.userName = userName; 296 297 helper.password = password; 298 299 300 301 NSArray * array = @[userName,password]; 302 303 NSString * data = [array componentsJoinedByString:@"-"]; 304 305 [data writeToFile:Path atomically:YES encoding:NSUTF8StringEncoding error:nil]; 306 307 } 308 309 310 311 + (void)logout { 312 313 314 315 NSFileManager * fm = [NSFileManager defaultManager]; 316 317 318 319 if ([fm fileExistsAtPath:Path]) { 320 321 [fm removeItemAtPath:Path error:nil]; 322 323 } 324 325 } 326 327 328 329 @end 330 331