詳解iPhone下如何獲取對象教程
詳解iPhone下如何獲取對象教程是本文要介紹的內容,主要是講述iPhone下如何獲取對象句柄和其父對象句柄,很詳細的讓我們去了解iphone中的對象,先來看詳細內容。
常規iPhone程序對象結構如下:
- 對象個數 對象類型
- 1 UIApplication
- 1 UIApplicationDelegate/subclass
- 1,N UIViewController/subclass
- 1,N UIView/subclsss
盡管有些書上說可以繞過UIViewController直接對UIView進行操作,但個人認為此層的作用用于管理視圖和視圖關系。
下面分別對上述層次關系的對象類型進行學習。說明下,下面學習的東西僅和問題有關,不會全面學習類中的各種方法和屬性。
UIApplication繼承于UIResponder:NSObject
框架:UIKit.framework
頭文件:UIApplication.h
每一個應用程序都有一個UIApplication或其子類型的實例。當程序被加載,函數方法UIApplicationMain就被調用執行,它創建了單件模式的UIApplication對象。之后你可以通過執行sharedApplication類方法來訪問。
看看main函數
- int main(int argc, char *argv[]){
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- int retVal = UIApplicationMain(argc, argv, nil, nil);
- [pool release];
- return retVal;
- }
可以看出,main函數的作用在于調用UIApplicationMain方法來創建一個UIApplication對象實例,同時也管理了此類的實例的內存釋放。
那么獲取UIApplication對象實例,代碼如下:
假設UIApplicationDelegate協議繼承類XXXXAppDelegate
- UIApplication *app = [UIApplication sharedApplication];
- XXXXAppDelegate *d = (XXXXAppDelegate *)app.delegate;
- //Test these code ,it is ok;
在main函數中創建了UIApplication實例,同時也就綁定了XXXXAppDelegate
看看原型
- int UIApplicationMain ( int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName );
- This function is called in the main entry point to create the application object and the application delegate and set up the event cycle.
- argc: The count of arguments in argv; this usually is the corresponding parameter to main.
- argv: A variable list of arguments; this usually is the corresponding parameter to main.
- principalClassName: The name of the UIApplicationclass or subclass.
- delegateClassName: The name of the class from which the application delegate is instantiated.
UIApplication部分:
- UIApplicationMain->
- UIApplication
UIApplicationDelegate實現類
- UIApplication->
sharedApplication類方法獲取當前程序的UIApplication實例
delegate屬性獲取UIApplicationDelegate實現類的實例
windows屬性獲取當前程序涉及到窗口類數組
keyWindow屬性獲取當前程序關鍵窗口
即然有了UIApplicationDelegate協議的實現類,那如何實現UIViewController/subclass的初始化?
實現Controller類的初始化的地方有兩處:
- application:didFinishLaunchingWithOptions:
- applicationDidFinishLaunching:
這兩個方法,后者是前期版本下的。在iOS3.0以及之后,應該使用前者來完成開始這個過程。XCode4運行的是application:didFinishLaunchingWithOptions:
當然,你也可以刪除application:didFinishLaunchingWithOptions:,自己添加applicationDidFinishLaunching方法來實現。不推薦此操作。
看下實際對UIApplicationDelegate如何編寫其實現類
- #import <UIKit/UIKit.h>
- @class NavSmallPhoneViewController;
- @interface NavSmallPhoneAppDelegate : NSObject <UIApplicationDelegate> {
- }
- @property (nonatomic, retain) IBOutlet UIWindow *window;
- @property (nonatomic, retain) IBOutlet NavSmallPhoneViewController *viewController;
- @end
- #import "NavSmallPhoneAppDelegate.h"
- #import "NavSmallPhoneViewController.h"
- @implementation NavSmallPhoneAppDelegate
- @synthesize window=_window;
- @synthesize viewController=_viewController;
- @synthesize info;
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
- // Override point for customization after application launch.
- selfself.window.rootViewController = self.viewController;
- [self.window makeKeyAndVisible];
- //Todo 這部分代碼是未測試和說明一個問題的:當前UIApplicationDelegate實現類中的window屬性來源哪?
- UIWindow *w = [UIApplication sharedApplication].keyWindow;
- NSLog(@"%@\n%@" ,w ,self.window);
- if (w == self.window)
- NSLog(@"AppDelegate 'window is UIApplication current keyWindow!");
- return YES;}
- /*為了方便閱讀,這里僅保留了需要看的方法。其他自動生成的代碼在此移除,看完整的,自己通過XCode4自動生成*/
- - (void)dealloc{
- [_window release];
- [_viewController release];
- [super dealloc];
- }
- @end
看頭文件,你發現實現類,有了兩個屬性,window和viewController;就是保存當前實現類所關聯的window和視圖控制器
通過運行,輸出“AppDelegate 'window is UIApplication current keyWindow!”,說明實現類的window屬性來源UIApplication實例當前的keyWindow屬性。
也就是說,如果UIApplication實例只有一份UIWindow實例,那肯定和其UIApplicationDelegate實現類的window屬性指向同一UIWindow實例。
之所以在UIApplicationDelegate實現類定義這么兩個屬性,就是為了更方便的使用UIWindow和UIViewController,作用就是建立對象樹狀關系,便于彼此調用和實現。
在這里,應該清楚了UIApplication和UIViewController之間是通過UIWinodw來關聯的,盡管在UIApplicationDelegate實現類中定義一個viewController屬性。修改下上面的關系圖:
常規iPhone程序對象結構如下:
- 對象個數 對象類型
- 1 UIApplication
- 1 UIApplicationDelegate/subclass
- 1 UIWindow
- 1 .rootViewController屬性
- 1,N UIViewController/subclass
- 1,N UIView/subclsss
根據現在的對象結構圖,可以知道UIWindow實例在此僅僅是起承上啟下的作用。
UIWindow繼承UIView:UIResponder:NSObject
現在可以看下UIViewController
#p#
繼承UIResponder:NSObject
UIViewController其子類UINavigationController和UITabBarController為復雜視圖控制器和視圖的層次結構提供額外的行為處理功能。
針對問題看下,有哪些視圖控制器可訪問?
- parentViewController property
- searchDisplayController property
- splitViewController property
- modalViewController property
- navigationController property
- tabBarController property
上述控制器訪問器都是只讀,說明這些控制器是由內部或初始化就進行處理。
從這里來看,至少可以說明一點,Controller之間的關聯是存在的
最關鍵,怎么去管理視圖?
屬性view和方法loadView
UIView又如何得到它的操作者?又如何管理自身的子視圖?
繼承于UIResponder:NSObject
如果UIView包含在UIViewController下,只能順起獲取到對應的UIView,暫時未知如何根據UIView獲取UIViewController
UIView關于管理視圖層次,如下:
Managing the View Hierarchy
- superview property
- subviews property
- window property
- – addSubview:
- – bringSubviewToFront:
- – sendSubviewToBack:
- – removeFromSuperview
- – insertSubview:atIndex:
- – insertSubview:aboveSubview:
- – insertSubview:belowSubview:
- – exchangeSubviewAtIndex:withSubviewAtIndex:
- – isDescendantOfView:
感覺可以通過屬性window來獲取Controller,從某一個角度來說,這個Controller應該是當前視圖的父對象
文中涉及紅色粗體,是本文的相關答案標記,如圖:
UIView.window屬性來源于當前UIApplication.keyWindow
可以通過此屬性讓UIView間接獲取到該視圖的UIViewController類。
小結:詳解iPhone下如何獲取對象教程的內容介紹完了,希望本文對你有所幫助!