类间两种关系:继承、 组合

来源:互联网 发布:ubuntu镜像下载地址 编辑:程序博客网 时间:2024/06/16 11:44

类间两种关系:继承、 组合。类间非继承关系,而调用了其它类的对象方法或访问了其它类的成员变量,那么他们间的关系统称组合关系。
广义上讲,组合也包含另两个特别的情况:单例访问、 通过根控制器或导航控制器找到对应页面控制器进行操作。
第一种关系:继承。
大家都知道通过父子类的继承关系,子类对象可以访问父类对象的公有成员变量和公有成员函数,这个就不多说了。
@interface SettingProfileHeadCell : SettingProfileCell
@property UIImageView *headImageView;
@property UILabel *describeLabel;
@end
第二种关系:普通组合关系。
类间的组合关系大家也经常用,一个类的成员对象是另一个类的对象。这个也不难了解。
它又包含两种情况:
1.生成的另一个类的对象是本类的一个成员对象。
2.生成的另一个类的对象是本类的成员函数的一个临时对象,随着本类的成员函数的调用结束,系统就销毁了该临时对象。
第一种情况:
生成的另一个类的对象是本类的一个成员对象的声明部分
@interface DrawMoneyViewController ()
{
}
@property CustomCommonNavigationBar *customCommonNavigationBar;
@end
@implementation DrawMoneyViewController
生成对象的部分:
- (void)setupSubViews {
self.view.backgroundColor = BACKGROUND_COLOR;
_customCommonNavigationBar = [[CustomCommonNavigationBar alloc] initWithLeftBtnImageName:@”NavBar_icon_Back_dark” LeftBtnShift:19 RightBtnTitle:@”” title:@”提现” titleIsBold:NO];
[self.view addSubview:_customCommonNavigationBar];
_customCommonNavigationBar.sd_layout
.leftSpaceToView(self.view, 0)
.rightSpaceToView(self.view, 0)
.topSpaceToView(self.view, 0)
.heightIs(64 + LINE_THICK); // 设置高度约束
[self loadButtonAction];
}
使用页面控制器包含的控件block:
-(void)loadButtonAction
{
[_customCommonNavigationBar backResult:^(BOOL iSuccess) {
[self.navigationController popViewControllerAnimated:YES];
}];
}

第二种情况:成员函数临时变量的数据序列化例子:
- (void)storageDataModelWithFileName:(NSString *)fileName
dataArr:(NSMutableArray *)dataArr;
{
if(![fileName isKindOfClass:[NSString class]] || ![dataArr isKindOfClass:[NSMutableArray class]] || (dataArr.count == 0))
{
return;
}
NSString *plistFileName = [fileName stringByReplacingOccurrencesOfString:@” ” withString:@”“];
if(plistFileName.length == 0)
{
return;
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSFileManager* fm = [NSFileManager defaultManager];
NSString *path=[paths objectAtIndex:0];
path = [path stringByAppendingPathComponent:LOCATION_DATA];
if (![fm fileExistsAtPath:path])
{
[fm createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
}
NSString *filePath = [path stringByAppendingPathComponent:plistFileName]; //获取路径
if([plistFileName isEqualToString:ORDER_CENTER_PLIST_FILE_NAME])
{
OrderOperateModel *orderOperateModel = nil;
NSMutableArray *arr = [NSMutableArray array];
for(NSUInteger i = 0; i < dataArr.count; i++)
{
OrderCellModel *model = dataArr[i];
if(![model isKindOfClass:[OrderCellModel class]])
{
return;
}
orderOperateModel = [[OrderOperateModel alloc] initWithDictionary:model];
[arr addObject:orderOperateModel];
}
if(arr.count > 0)
{
NSData * tempArchive = [NSKeyedArchiver archivedDataWithRootObject:arr];
[tempArchive writeToFile:filePath atomically:YES];
}
}
}
第二种情况:成员函数临时变量的页面跳转例子:
-(void)openOnlineServiceViewController : (NSMutableDictionary *)orderInfo
{
OnlineServiceViewController *onlineServiceViewController = [OnlineServiceViewController new];
[onlineServiceViewController displayOrderInfo : orderInfo];
[self.navigationController pushViewController:onlineServiceViewController animated:YES];
}

特殊的组合关系:单例访问。
一个类的对象中的函数可以访问全局的单例。
使用系统的单例的block:
__weak typeof(self) weakSelf = self;
AppDelegate app = (AppDelegate )[UIApplication sharedApplication].delegate;
[app regisiterXYContinueListenOrderCallback:^{
[weakSelf continueListenOrder];
}];
使用单例的变量:
[SingleObject sharedInstance].keyboardWasShownFlag = NO;
使用单例的函数:

[[SingleObject sharedInstance] initData];
使用单例的block:

[[SocketManager shareInstance] regisiterOnlineServiceCallBackMessageCallBack:^(NSMutableDictionary *message) {    [weakSelf handleMessageWithMessage:message];}];

特殊的组合关系:通过根控制器或导航控制器找到对应页面控制器进行操作。
它和第二种关系的主要区别是它不是直接在本类生成该对象,而是找到已经存在的对象,并进行操作。
它和第三种关系的主要区别是它不是直接找到该对象,而是通过根控制器(也可能是导航控制器)找到,甚至根控制器(也可能是导航控制器)也是被间接找到的。
在一个页面控制器里可以通过导航控制器找到其它页面控制器,对它的公有成员数据进行赋值,也可以对它的公有函数进行调用,一般近接着就要跳到找到的这个页面控制器。
-(void)openOnlineServiceViewController : (NSMutableDictionary *)orderInfo
{
for (UIViewController *viewController in self.navigationController.viewControllers) {
if ([viewController isKindOfClass:[OnlineServiceViewController class]]) {
OnlineServiceViewController onlineServiceViewController = (OnlineServiceViewController )viewController;
[self.navigationController popToViewController:onlineServiceViewController animated:YES];
return;
}
}
OnlineServiceViewController *onlineServiceViewController = [OnlineServiceViewController new];
[onlineServiceViewController displayOrderInfo : orderInfo];
[self.navigationController pushViewController:onlineServiceViewController animated:YES];
}
在一个页面控制器里或非页面控制器里可以通过keyWindow找到rootViewController,然后通过它可以找到本导航控制器,然后通过本导航控制器找到指定的页面控制器,对它的公有成员数据进行赋值,也可以对它的公有函数进行调用,一般近接着就要跳到找到的这个页面控制器。
所以这种情况算着上一种情况的一种特殊情况。
使用这种方式找页面控制器时要注意一下三种情况:
1.当你在高德导航地图页面,你找到的就不是rootViewController了,是导航地图图层。
2.若你的页面出现了循环跳转,当使用该方法循环跳转了多次,你再用该种方法找页面可能出现异常情况(我的首页使用了两个子试图,一个做侧边栏,一个作普通的首页,在两个子试图间产生页面循环,使用该方法多次循环跳转后崩溃。估计普通的循环页面跳转使用该方法不会产生崩溃)。
3.当你的页面有多于一个导航控制器时(如:有侧边栏的应用),要注意导航控制器的层级。
-(void)goToLoginViewControlNotification
{
NSArray *cv = [[self getCurrentVC] childViewControllers];
NSLog(@”%@”,cv);
if(cv.count == 0)
{
return;
}
[[GlobalShare getGlobalShare] clearUserInfo];
UIViewController viewCtrl = (UIViewController )(cv[0]);

if([viewCtrl isKindOfClass:[LoginViewController class]]){    return;}for (UIViewController *viewController in self.navigationController.viewControllers) {    if ([viewController isKindOfClass:[LoginViewController class]]) {        [self.navigationController popToViewController:viewController animated:YES];    }}

}

  • (UIViewController *)getCurrentVC
    {
    UIViewController *result = nil;

    UIWindow * window = [[UIApplication sharedApplication] keyWindow];
    if (window.windowLevel != UIWindowLevelNormal)
    {
    NSArray *windows = [[UIApplication sharedApplication] windows];
    for(UIWindow * tmpWin in windows)
    {
    if (tmpWin.windowLevel == UIWindowLevelNormal)
    {
    window = tmpWin;
    break;
    }
    }
    }
    UIView *frontView = [[window subviews] objectAtIndex:0];
    id nextResponder = [frontView nextResponder];

    if ([nextResponder isKindOfClass:[UIViewController class]])
    result = nextResponder;
    else
    result = window.rootViewController;

    return result;
    }

0 0