Objective-C编程:在类的外部声明全局变量
2013-09-05 11:07
134 查看
近来学习iOS开发,在研究通知中心的机制(notification center)时,编写了如下代码进行尝试,首先自定义一个类:
然后在AppDelegate类里注册UIDeviceOrientationDidChangeNotification事件:
经观察,发现,Test1NotificationMy1的对象my1是一个局部变量,生存周期仅在application:didFinishLaunchingWithOptions:方法内部有效,而UIDeviceOrientationDidChangeNotification事件的发生有可能是在该方法结束之后,这时my1变量已经无效了。而为什么类方法orientationChange:能够正常调用呢,这是因为类对象
在整个应用的生存周期内一直存在,无论何时发生UIDeviceOrientationDidChangeNotification事件,类方法都能够被调用。
为了让实例方法orientationChangeInstance:也能够被调用,可以把对象my1作为外部变量声明:
这样,就可以实现预期的效果。在iPhone或设备模拟器上运行程序,当设备转动方向时,控制台会输出如下信息:
总结:Objective-C虽然有很多面向对象的特性,但是它同样也是C语言的扩展,C语言所支持的特性同样也受Objective-C支持,比如在上述例子中,可以在类的外部声明变量。当然,这种做法违反了面向对象的设计原则,在实际项目中,如果要制造一个在整个程序的生命周期都能够使用的对象,正确的做法是使用单例模式。
@interface Test1NotificationMy1 : NSObject +(void) orientationChange:(NSNotification *)note; -(void) orientationChangeInstance:(NSNotification *)note; @end
@implementation Test1NotificationMy1 +(void) orientationChange:(NSNotification *)note { NSLog(@"类方法:方向变化了:%d", [[note object] orientation]); } -(void) orientationChangeInstance:(NSNotification *)note { NSLog(@"实例方法:方向变化了:%d", [[note object] orientation]); }
然后在AppDelegate类里注册UIDeviceOrientationDidChangeNotification事件:
@implementation Test1NotificationAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. UIDevice *device = [UIDevice currentDevice]; [device beginGeneratingDeviceOrientationNotifications]; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:[Test1NotificationMy1 class] selector:@selector(orientationChange:) name:UIDeviceOrientationDidChangeNotification object:device]; Test1NotificationMy1 *my1 = [[Test1NotificationMy1 alloc] init]; [nc addObserver:my1 selector:@selector(orientationChangeInstance:) name:UIDeviceOrientationDidChangeNotification object:device]; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES;}//...@end运行时发现,自定义类的类方法orientationChange:能够正常调用,而实例方法orientationChangeInstance:却不能调用。程序会在控制台输出
类方法:方向变化了:5之后崩溃退出。而注释掉实例接受方法之后,程序正常运行。
//注释掉下面这一行 //[nc addObserver:my1 selector:@selector(orientationChangeInstance:) name:UIDeviceOrientationDidChangeNotification object:device];
经观察,发现,Test1NotificationMy1的对象my1是一个局部变量,生存周期仅在application:didFinishLaunchingWithOptions:方法内部有效,而UIDeviceOrientationDidChangeNotification事件的发生有可能是在该方法结束之后,这时my1变量已经无效了。而为什么类方法orientationChange:能够正常调用呢,这是因为类对象
[Test1NotificationMy1 class]
在整个应用的生存周期内一直存在,无论何时发生UIDeviceOrientationDidChangeNotification事件,类方法都能够被调用。
为了让实例方法orientationChangeInstance:也能够被调用,可以把对象my1作为外部变量声明:
#import "Test1NotificationAppDelegate.h" #import "Test1NotificationMy1.h" //在类的外部声明变量 static Test1NotificationMy1 *my1; @implementation Test1NotificationAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //... my1 = [[Test1NotificationMy1 alloc] init]; [nc addObserver:my1 selector:@selector(orientationChangeInstance:) name:UIDeviceOrientationDidChangeNotification object:device]; //... } //... @end
这样,就可以实现预期的效果。在iPhone或设备模拟器上运行程序,当设备转动方向时,控制台会输出如下信息:
2013-09-05 10:18:11.503 Test1Notification[4085:907] 类方法:方向变化了:5 2013-09-05 10:18:11.505 Test1Notification[4085:907] 实例方法:方向变化了:5
总结:Objective-C虽然有很多面向对象的特性,但是它同样也是C语言的扩展,C语言所支持的特性同样也受Objective-C支持,比如在上述例子中,可以在类的外部声明变量。当然,这种做法违反了面向对象的设计原则,在实际项目中,如果要制造一个在整个程序的生命周期都能够使用的对象,正确的做法是使用单例模式。
相关文章推荐
- 详解keil采用C语言模块化编程时全局变量、结构体的定义、声明以及头文件包含的处理方法!
- Objective-C中使用extern引用外部全局变量(如:创建全局可变字符串)
- 嵌入式C编程中的全局变量重复声明问题
- keil 中——C语言模块化编程时全局变量、结构体的定义、声明以及头文件包含的处理方法
- 详解keil采用C语言模块化编程时全局变量、结构体的定义、声明以及头文件包含的处理方法
- 详解keil采用C语言模块化编程时全局变量、结构体的定义、声明以及头文件包含的处理方法!
- c++中静态成员变量 静态成员函数 全局变量与静态函数的关系 字符串中括号的匹配编程 (笔试经历)
- C++全局变量的声明和定义
- 正确声明全局变量
- C++全局变量的声明和定义
- 全局变量不能在函数外部赋值.
- c/c++中extern用来声明全局变量
- extern 声明全局变量,多文件使用
- 怎样定义和声明全局变量和函数最好?
- C语言中const分析(未知大小的全局变量数组声明出错)
- 基于C++全局变量的声明与定义的详解
- 如何合理的声明JavaScript变量,避免污染全局变量
- C++全局变量尽量写在stdafx.cpp中 extern 关键字找不到外部定义就等于新定义
- JavaScript声明全局变量三种方式的异同
- Java第11次作业:什么是继承?继承的好处?什么是覆写?super()?构造代码块?子父类初始化顺序? 抽象类能用final声明吗?final关键字声明类 方法 变量以及全局常量?抽象类的构造方法?