zoukankan      html  css  js  c++  java
  • 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.

    self.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
    继承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类








    无论生活、还是技术,一切都不断的学习和更新~~~努力~
  • 相关阅读:
    Python反射机制
    并发和并行的区别
    I/O模型
    python 字符串零散方法记录
    python 关于占位符格式化
    Python 十进制转二进制、八进制、十六进制
    python中str函数isdigit、isdecimal、isnumeric的区别
    文件的修改
    LF 模块三
    stackoverflow os.path.abspath and os.path.realpath
  • 原文地址:https://www.cnblogs.com/GoGoagg/p/2064324.html
Copyright © 2011-2022 走看看