在Objective-C中,我想知道自定义setter是否会覆盖KVO支持(willChangeValueForKey:和didChangeValueForKey;)并且我是否需要在自定义setter中明确包含对这些的调用?
保留和复制怎么样?我是否需要明确地包含发布并保留或复制具有保留或复制属性(对于非ARC代码)的属性的setter?
我正在尝试观察NSMutableString的更改isDetailView:
-(void)viewDidLoad {
[self addObserver:self forKeyPath:@"isDetailView" options:NSKeyValueObservingOptionNew context:nil];
[isDetailView setString:@"YES"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"obersedValueFOrKeyPath:%@", keyPath);
}
Run Code Online (Sandbox Code Playgroud)
但是从不调用observeValueForKeyPath方法.有任何想法吗?
我正在尝试查看哈希并将其值与现有字符串进行比较,然后在找到匹配项时我想输出其密钥.我试图在代码块中写这个并将结果输出到控制台.
officer.name = "Dave"
@hash = { "Tom" => "97", "Dave" => "98", "John" => "99" }
@hash.each { |key, value| do
if #{key} == officer.name
puts "id: #{value}"
else
puts "no match"
end
}
Run Code Online (Sandbox Code Playgroud)
现在我的控制台输出:
id: 97
no match
id: 98
no match
id: 99
no match
Run Code Online (Sandbox Code Playgroud)
我试图让它只输出#{value}的值,基于匹配的#{key},在这种情况下是Dave.所以对于上面的例子,我希望我的控制台只吐出数字98或"不匹配".
我需要我的类的实例观察它自己的属性,所以我设置观察:
[self addObserver:self forKeyPath:@"myProperty" options:NSKeyValueObservingOptionNew context:nil]
Run Code Online (Sandbox Code Playgroud)
在dealloc中只需检查并删除观察者:
- (void)dealloc
{
if ([self observationInfo])
{
[self removeObserver:self];
}
}
Run Code Online (Sandbox Code Playgroud)
这个项目属于ARC,在iOS 6 SDK之前一切正常.但是使用iOS 6 SDK,observationInfo在dealloc使用EX_BAD_ACCESS(释放消息发送到解除分配的实例)之后,会增加对象和应用程序的retainCount 崩溃.
这段代码有什么问题?这是Apple的BUG还是我的?
更新 有栈跟踪:
thread #1: tid = 0x1f03, 0x016b60ab libobjc.A.dylib`objc_release + 27, stop reason = EXC_BAD_ACCESS (code=1, address=0xff000002)
frame #0: 0x016b60ab libobjc.A.dylib`objc_release + 27
frame #1: 0x016b6bd9 libobjc.A.dylib`(anonymous namespace)::AutoreleasePoolPage::pop(void*) + 555
frame #2: 0x02538468 CoreFoundation`_CFAutoreleasePoolPop + 24
frame #3: 0x0253cafd CoreFoundation`__CFRunLoopRun + 1933
frame #4: 0x0253bf44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #5: 0x0253be1b …Run Code Online (Sandbox Code Playgroud) 如何找出对象何时被释放?我正在监听kvo更改,但是在保留计数变为0之前对象被取消分配,并且我收到以下警告:
MyViewController类的实例0x16562be0已取消分配,而键值观察者仍在其中注册.观察信息被泄露,甚至可能被错误地附加到其他物体上.在NSKVODeallocateBreak上设置断点以在调试器中停止.这是目前的观察信息:
基本上我要做的是检测模型何时被解雇.我不能使用Delegate,因为呈现的viewControllers是动态的,我的mainViewController除了它们是UIViewController的子类之外不了解它们.
[anotherViewController addObserver:self forKeyPath:@"retainCount" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionOld | NSKeyValueObservingOptionPrior context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
// Here check for the changes and see of the new value is 0 or not
}
Run Code Online (Sandbox Code Playgroud)
我也试着监听viewController的superView被改为nil
[anotherViewController.view addObserver:self forKeyPath:@"superView" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionOld | NSKeyValueObservingOptionPrior context:nil];
Run Code Online (Sandbox Code Playgroud) 我有一个定义属性的 ClassA:
@interface ClassA : NSObject
@property (nonatomic) CGPoint property;
@end
Run Code Online (Sandbox Code Playgroud)
该实现不会覆盖访问器。
ClassB 覆盖 setter 来做一些额外的工作:
- (void)setProperty:(CGPoint)property {
[super setProperty:property];
[self someAdditionalWork];
}
Run Code Online (Sandbox Code Playgroud)
在 ClassB 的另一种方法中,我尝试通过超级设置器设置此属性,以跳过额外的工作:
- (void)otherMethodInClassB {
// ...
super.property = newValue;
// ...
}
Run Code Online (Sandbox Code Playgroud)
当我这样做时,不会发送该属性的 KVO 通知。如果我做同样的事情,但使用self,KVO 通知按预期工作:
- (void)otherMethodInClassB {
// ...
self.property = newValue;
// ...
}
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?这是预期的行为吗?我找不到任何可以这样说的东西。
我想NSArray为声明为的属性实现KVO readonly.此readonly属性的getter 返回私有的副本,该私有NSMutableArray备份支持公共的副本readonly:
在我的.h:
@interface MyClass : NSObject
@property (readonly, nonatomic) NSArray *myArray;
- (void)addObjectToMyArray:(NSObject *)obj;
- (void)removeObjectFromMyArray:(NSObject *)obj;
@end
Run Code Online (Sandbox Code Playgroud)
在我的.m:
@interface MyClass()
@property (strong, nonatomic) NSMutableArray *myPrivateArray;
@end
@implementation MyClass
- (NSArray *)myArray {
return (NSArray *)[self.myPrivateArray copy];
}
- (void) addObjectToMyArray:(NSObject *)obj {
[self willChangeValueForKey:@"myArray"];
[self.myPrivateArray addObject:obj];
[self didChangeValueForKey:@"myArray"];
}
- (void) removeObjectToMyArray:(NSObject *)obj {
[self willChangeValueForKey:@"myArray"];
[self.myPrivateArray removeObject:obj];
[self didChangeValueForKey:@"myArray"];
}
@end
Run Code Online (Sandbox Code Playgroud)
在我的测试中,我看到我打电话时抛出异常didChangeValueForKey: …
我正在使用在 iOS 10.0 下运行的 swift 3.0,我想制作一些在满足批处理条件时触发的代码。
for i in 0 ..< rex {
async code, disappears and does it stuff
}
Run Code Online (Sandbox Code Playgroud)
想象一下异步代码是一个 URL 请求的集合,只要我循环它们,基本上就是背景。现在如何在“rex”请求完成后触发更多代码?
我想设置一个计时器来每秒观察和检查,但这肯定不是一个好的解决方案。
我想启动另一个线程来简单地观察正在收集的数据,并在其配额已满时触发,但这确实比计时器更糟糕。
我想在每个 URL 请求的末尾包含一个测试,看看它是否是最后一个完成的而不是使用 NotificationCenter,但这是最佳解决方案吗?
我的keyPathsForValuesAffecting<key>方法有问题。我想通知观察者fullName何时name或surname已更改。但是不幸的是没有通知观察者。
我的代码:
将要观察的课程:
class DependencyTest: NSObject {
@objc dynamic var fullName: String {
return name + " " + surname
}
@objc var name = ""
@objc var surname = ""
class func keyPathsForValuesAffectingFullName() -> Set<NSObject> {
return ["name" as NSObject, "surname" as NSObject]
}
}
Run Code Online (Sandbox Code Playgroud)
观察者ViewController:
let dep = DependencyTest()
override func viewDidLoad() {
super.viewDidLoad()
addObserver(self, forKeyPath: "dep.fullName", options: .prior, context: nil)
dep.name = "bob" // Im expecting that `observeValue:` method …Run Code Online (Sandbox Code Playgroud) 奇怪的语法,但我想问一下,如果有的话,如果我不KVO(键值观察),应用程序只是不能做某些事情/功能?
谢谢
objective-c ×7
ios ×4
swift ×2
alamofire ×1
arrays ×1
cocoa-touch ×1
hash ×1
ios6 ×1
kvc ×1
nsurl ×1
properties ×1
ruby ×1