前言
本篇文章讲讲述一下OC中的单例(singleton)模式、使用点语法访问属性、判断指针变量实际类型。
一、单例(singleton)模式
当我们运行代码的时候,有时程序会多次创建某个类的对象,这种情况不仅没有任何意义可能使得系统性能下降例如多次创建对象并回收对象给系统带来的开销问题。此时程序就需要保证该类只有一个实例,于是单例模式就该提出来了。
1.定义
如果一个类无论多少次都只能创建一个对象那么这个类就被称为单例类。
2.实现方法
我们可以通过static这个全局变量来实现,我们首先定义一个static全局变量来保存已创建的singleton对象,每次需要获取该实例时先判断static是否为nil,如果为nil则初始化一个实例并赋给static,如果static不为空则直接返回这个全局变量指向的实例。
3.示例代码
FKSingleton.h
@interface FKSingleton: NSObject
+ (id)instance;
@end
FKSingleton.m
#import <Foundation/Foundation.h>
#import "FKSingleton.h"
@implementation FKSingleton
static id instance = nil;//定义一个全局变量instance
+ (id)instance {
if (!instance) {//判断instance全局变量是否为nil,如果为nil则创建一个Singleton实例并赋给instance全局变量
instance = [ [super alloc] init];
}
return instance;
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {//判断两次获取的实例是否相等如果相等则程序返回1
NSLog(@"%d", [FKSingleton instance] == [FKSingleton instance]);
}
return 0;
}
4.运行结果
二、使用点语法访问属性
在介绍点语法之前我们先看下面这段代码:
synthetic_access_method.h
@interface synthetic_access_method: NSObject
@property (nonatomic)NSString* name;
@property (nonatomic)NSString* age;
@property NSDate* birth;
@end
synthetic_access_method.m
#import <Foundation/Foundation.h>
#import "Header.h"
@implementation synthetic_access_method
@synthesize name = _name;
@synthesize age;
@synthesize birth;
- (void)setName:(NSString *)name {//如果程序调用了自定义的setName方法则会在名字前增加+++的前缀
self->_name = [NSString stringWithFormat:@"+++%@", name];
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
synthetic_access_method* object = [[synthetic_access_method alloc] init];
[object setName: @"张三"];
[object setAge: @"18"];
[object setBirth: [NSDate date]];
NSLog(@"姓名:%@,年龄:%@,生日:%@", [object name],[object age], [object birth]);
}
return 0;
}
通过这段代码我们可以知道我们每次设置和访问属性值时都需要通过setter和getter方法完成,但其实我们还可以通过点语法访问属性和对属性赋值。
1.定义
点语法的本质还是调用getter和setter方法,当程序通过点语法来获取指定对象的属性值的时候本质上还是获取该对象的getter方法的返回值,因此,只要该对象有getter方法就能通过点语法来获取属性值。当程序通过点语法设置属性值的时候本质上还是通过setter方法设置,因此,只要该对象有setter方法就能通过点语法来设置属性值。
2.实现方法
“.”+属性名
因此,刚才那段代码可以直接写成:
synthetic_access_method.h
@interface synthetic_access_method: NSObject
@property (nonatomic)NSString* name;
@property (nonatomic)NSString* age;
@property NSDate* birth;
@end
main.m
#import <Foundation/Foundation.h>
#import "Header.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
synthetic_access_method* object = [[synthetic_access_method alloc] init];
[object setBirth: [NSDate date]];
object.name = @"李四";
object.age = @"19";
NSLog(@"姓名:%@,年龄:%@,生日:%@", [object name],[object age], [object birth]);
}
return 0;
}
需要注意的是使用点语法访问属性的时候可以直接用“.”+属性名,而使用“->"访问属性的时候则不能省略成员变量名前的下划线“_”否则会报错。
三、判断指针的实际类型
我们知道OC指针类型的变量有两个,一个是编译时的类型,一个是运行时的类型,当编译时的类型和运行时的类型不一致时就会出现多态,此时程序就会运行失败,就需要执行强制类型转换为了程序能够正常运行,一般建议在执行强制类型转换之前先判断对象是否为该类的或其子类的实例。
1.实现方法
- (BOOL)isMemberOfClass: clazz://判断该对象是否为clazz类的实例
- (BOOL)isKindOfClass: clazz://判断该对象是否为clazz类或其子类的实例
+ (BOOL)isSubclassOfClass: clazz://这是类方法,用于判断当前类是否为clazz的子类
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSObject* hello = @"hello";
NSLog(@"字符串是否是NSObject类的实例:%d", ([hello isKindOfClass:[NSObject class]]));
NSLog(@"字符串是否是NSString类的实例:%d",([hello isKindOfClass:[NSString class]]));
NSString* a = @"hello";
NSLog(@"a是否是NSDate类的实例:%d",([a isKindOfClass:[NSDate class]]));
}
return 0;
}
总结
以上就是本篇文章的全部内容,如果对你有帮助的话请点赞支持一下~