作为Objective-c,cocoa和iPhone开发人员的新手,我强烈希望充分利用语言和框架.
我正在使用的资源之一是斯坦福大学的CS193P课程,他们已经留在网上了.它包括讲义,作业和示例代码,由于课程由Apple开发者提供,我绝对认为它是"从马的嘴里".
课程网站:http:
//www.stanford.edu/class/cs193p/cgi-bin/index.php
第08讲与构建基于UINavigationController的应用程序的任务相关,该应用程序将多个UIViewControllers推送到UINavigationController堆栈.这就是UINavigationController的工作原理.这是合乎逻辑的.但是,幻灯片中有一些关于UIViewControllers之间通信的严厉警告.
我将引用这个严肃的幻灯片:http:
//cs193p.stanford.edu/downloads/08-NavigationTabBarControllers.pdf
第16/51页:
如何不共享数据
- 全局变量或单例
- 这包括您的申请代表
- 直接依赖使您的代码不再可重用
- 而且更难以调试和测试
好.我很失望.不要盲目地将所有用于在viewcontroller之间进行通信的方法扔到app委托中,并引用app delegate方法中的viewcontroller实例.公平的'努力.
再进一步说,我们得到这张幻灯片告诉我们应该做些什么.
第18/51页:
数据流的最佳实践
- 弄清楚究竟需要传达什么
- 定义视图控制器的输入参数
- 要进行备份层次结构的通信,请使用松散耦合
- 为观察者定义通用接口(如委托)
然后,这张幻灯片后面会出现一个占位符幻灯片,然后讲师显然会使用UIImagePickerController的示例演示最佳实践.我希望这些视频可用!:(
好吧,所以...我担心我的objc-fu不是那么强大.我也对上面引用的最后一行感到困惑.我一直在谷歌搜索关于这一点,我发现似乎是一篇体面的文章谈论观察/通知技术的各种方法:http:
//cocoawithlove.com/2008/06/five-approaches-to -listening-observing.html
方法#5甚至表示委托作为一种方法!除了....对象一次只能设置一个委托.所以当我有多个viewcontroller通信时,我该怎么办?
好的,那是设置团伙.我知道我可以通过引用在我的appdelegate中的多个viewcontroller实例轻松地在app委托中执行我的通信方法,但我想以正确的方式做这种事情.
请回答以下问题,帮助我"做正确的事":
iphone cocoa-touch delegates objective-c key-value-observing
如果是这样,在Objective-C中使用键值观察时是否存在其他不存在的关键差异?
我通常会看到这个问题是另一种方式,例如每个伊娃都必须是财产吗?(我喜欢bbum对这个Q的回答).
我几乎只在我的代码中使用属性.然而,每隔一段时间,我就与一位长期在iOS上开发并且是传统游戏程序员的承包商合作.他编写的代码几乎没有声明任何属性,并且依赖于ivars.我认为他这样做是因为1.)他已经习惯了,因为在Objective C 2.0(2007年10月)和2)之前,属性并不总是存在,因为没有经过getter/setter的最小性能增益.
虽然他编写了不泄漏的代码,但我仍然希望他使用ivars上的属性.我们讨论过它,他或多或少看不到使用属性的理由,因为我们没有使用KVO,而且他在处理内存问题方面经验丰富.
我的问题更多......为什么你会想要使用伊娃时期 - 经验丰富与否.使用ivar真的有很大的性能差异吗?
另外作为澄清点,我根据需要覆盖了setter和getter,并使用与getter/setter中的属性相关的ivar.但是,在getter/setter或init之外,我总是使用self.myProperty语法.
我感谢所有好的回应.我想解决的一个看起来不正确的是,使用ivar你可以获得封装,而不是使用属性.只需在类继续中定义属性即可.这会将财产隐藏在外人之外.您还可以在接口中声明属性readonly,并在实现中将其重新定义为readwrite,如:
// readonly for outsiders
@property (nonatomic, copy, readonly) NSString * name;
Run Code Online (Sandbox Code Playgroud)
并在课堂上继续:
// readwrite within this file
@property (nonatomic, copy) NSString * name;
Run Code Online (Sandbox Code Playgroud)
让它完全"私有"只在类继续中声明它.
如果你告诉一个目标c对象removeObservers:对于一个关键路径并且该关键路径尚未注册,它会破坏sads.喜欢 -
'无法删除关键路径"theKeyPath"的观察者,因为它未注册为观察者.
有没有办法确定一个对象是否有一个注册的观察者,所以我可以做到这一点
if (object has observer){
remove observer
}
else{
go on my merry way
}
Run Code Online (Sandbox Code Playgroud) 如何从ARC下的对象中删除观察者?我们只是添加观察者并忘记删除它吗?如果我们不再手动管理内存,我们会从观察中退出吗?
例如,在视图控制器上:
[self.view addObserver:self
forKeyPath:@"self.frame"
options:NSKeyValueObservingOptionNew
context:nil];
Run Code Online (Sandbox Code Playgroud)
以前,我会调用removeObserver:视图控制器的dealloc方法.
我想看了在变化UIView的frame,bounds或center财产.我如何使用Key-Value Observing来实现这一目标?
类具有NSMutableArray类型的属性(和实例var),具有合成访问器(via @property).如果使用以下方法观察此数组:
[myObj addObserver:self forKeyPath:@"theArray" options:0 context:NULL];
Run Code Online (Sandbox Code Playgroud)
然后在数组中插入一个对象,如下所示:
[myObj.theArray addObject:NSString.string];
Run Code Online (Sandbox Code Playgroud)
不发送observeValueForKeyPath ...通知.但是,以下内容确实发送了正确的通知:
[[myObj mutableArrayValueForKey:@"theArray"] addObject:NSString.string];
Run Code Online (Sandbox Code Playgroud)
这是因为mutableArrayValueForKey返回一个负责通知观察者的代理对象.
但是,合成访问器不应该自动返回这样的代理对象吗?解决这个问题的正确方法是什么 - 我应该编写一个只调用的自定义访问器[super mutableArrayValueForKey...]吗?
我想知道在观察属性时应该在KVO中设置Context指针.我刚开始使用KVO而且我没有从文档中收集到太多东西.我在这个页面上看到:http://www.jakeri.net/2009/12/custom-callout-bubble-in-mkmapview-final-solution/作者这样做:
[annView addObserver:self
forKeyPath:@"selected"
options:NSKeyValueObservingOptionNew
context:GMAP_ANNOTATION_SELECTED];
Run Code Online (Sandbox Code Playgroud)
然后在回调中,这样做:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context{
NSString *action = (NSString*)context;
if([action isEqualToString:GMAP_ANNOTATION_SELECTED]){
Run Code Online (Sandbox Code Playgroud)
我假设在这种情况下,作者只是创建一个字符串,以便稍后在回调中识别.
然后在iOS 5 Pushing the Limits一书中,我看到他这样做:
[self.target addObserf:self forKeyPath:self.property options:0 context:(__bridge void *)self];
Run Code Online (Sandbox Code Playgroud)
打回来:
if ((__bridge id)context == self) {
}
else {
[super observeValueForKeyPath .......];
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否有传递到上下文指针的标准或最佳实践?
在使用对象观察值时addObserver:forKeyPath:options:context:,最终您将要调用removeObserver:forKeyPath:该对象以便稍后进行清理.在此之前,是否可以检查对象是否实际上正在观察该属性?
我试图在我的代码中确保一个对象只在需要时删除了一个观察者,但在某些情况下,观察者可能会尝试将自己移除两次.我正在努力防止这种情况,但为了以防万一,我一直在试图弄清楚是否有办法首先检查我的代码是否真的是一个东西的观察者.
我注意到没有代表观察UIDatePicker中的更改.有没有办法检测何时在选择器中进行更改而不确认任何内容,例如它旋转并落在我希望能够检测到的新数字上的那一刻.我考虑过关键值观察,但我不认为有一个属性会在现场发生变化
objective-c ×7
ios ×5
cocoa ×2
cocoa-touch ×2
iphone ×2
delegates ×1
ivar ×1
key ×1
swift ×1
uidatepicker ×1
uiview ×1