我试图通过将属于UIView
的代码与属于UIViewController
的代码分开来重新组织早期项目。回答一个受欢迎的问题(found here)似乎并没有解决我需要做的事情,让我用两个例子来说明我的问题。使用getters和setters将消息从父UIViewController传递给UIView类中的方法?
- 实施例1
这里setBackground:zone
改变视图的背景颜色,以指示该应用的各种状态的方法。方法如下所示当前有效,我想将代码重定位到它所属的视图。
ViewController.h
#import <UIKit/UIKit.h>
#import "CustomView.h"
@interface ViewController : UIViewController {
}
@end
ViewController.m
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
int zone = 1; // or 2 or 3;
self.view = [[UIView alloc] initWithFrame: [UIScreen mainScreen].bounds];
[self setBackground:zone];
}
- (void)setBackground:(int)zone {
switch (zone) {
case 1:
self.view.backgroundColor = [UIColor orangeColor];
break;
case 2:
self.view.backgroundColor = [UIColor cyanColor];
break;
case 3:
self.view.backgroundColor = [UIColor greenColor];
break;
default:
break;
}
}
- 实施例2
在下面的代码我试着在CustomView
上使用getter和setter来引用zone
的值ViewController
(适当的为ViewControllers
在原始项目中已经获得并且设置为zone
以改变背景颜色)的值初始化背景颜色。
CustomView.h
CustomView.m
#import "CustomView.h"
@implementation CustomView
- (void)setParent:(UIViewController *)theParent {
parent = theParent;
}
- (int)getSelectedZone {
return selectedZone;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:[UIScreen mainScreen].bounds];
if (self) {
NSLog(@"selectedZone in CustomView is seen as %i", [self getSelectedZone]);
int zone = [self getSelectedZone];
[self setBackground:(int) zone];
}
return self;
}
- (void)setBackground:(int)zone {
switch (zone) {
case 1:
self.view.backgroundColor = [UIColor orangeColor];
break;
case 2:
self.view.backgroundColor = [UIColor cyanColor];
break;
case 3:
self.view.backgroundColor = [UIColor greenColor];
break;
default:
break;
}
}
ViewController.h
#import <UIKit/UIKit.h>
#import "CustomView.h"
@interface ViewController : UIViewController {
int selectedZone;
}
- (void)setSelectedZone:(int)zone;
- (int)getSelectedZone;
ViewController.m
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
int zone = 1; // or 2 or 3;
[self setSelectedZone:(int)zone];
NSLog(@"selectedZone in ViewController is now set to %i", [self getSelectedZone]);
self.view = [[UIView alloc] initWithFrame: [UIScreen mainScreen].bounds];
CustomView *cv = [[CustomView alloc]init];
[self.view addSubview:cv];
}
- (void)setSelectedZone:(int)zone {
selectedZone = zone;
}
- (int)getSelectedZone {
return selectedZone;
}
我可以告诉我的代码以上不起作用,因为getSelected:zone
在CustomView
不能引用zone
通过setSelected:zone
在ViewController.
设置,但我不明白为什么。
2017-04-05 07:04:26.126 ZoneIndicator[1865:1270743] selectedZone in ViewController is now set to 1
2017-04-05 07:04:26.126 ZoneIndicator[1865:1270743] selectedZone in CustomView is seen as 0
但an article found here甚至让我怀疑使用getter和setter方法是否是最好的方法 - 尤其是这样的:
最大的危险在这里的是,通过询问数据从一个对象,你 是只获取数据。你没有得到一个对象 - 不是在大的 意义上。即使您从查询中收到的东西在结构上是对象 (例如,,一个字符串)它不再是一个对象的语义。 它不再与其所有者对象有任何关联。只是因为 你得到了一个字符串,其内容是“红色”,你不能问字符串 这意味着什么。它是业主的姓氏吗?汽车的颜色? 转速表的当前状况?一个对象知道这些事情, 数据没有。
那么如何将消息从父UIViewController传递给UIView类中的方法?
DANH,感谢您的详细解释。这是我在项目中缺少的完美简单解决方案。我必须考虑“不明智地给视图一个指向它的视图控制器的指针(并且更加不明智地称这个指针为”parent“)。 – Greg
:-)高兴地帮助。命名要点是UIView使用“parent”来引用它出现的视图,而不是管理它的视图控制器。保持指针不明智的原因更多的是关于设计传统,强大的所有权和信息流从*视图控制器*转到*视图,而不是其他方式。意见有时确实需要在该链上反向沟通,而通常的做法是“委托”。 – danh