setProperty now releases old property

fix for c++ destructors in Linux
renamed instance variables in binder classes
This commit is contained in:
Johannes Fortmann 2008-03-31 16:11:19 +00:00
parent eb55681783
commit 532e5084c3
9 changed files with 150 additions and 145 deletions

View File

@ -11,12 +11,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
@class NSString, NSMutableDictionary, NSValueTransformer;
@interface _NSBinder : NSObject {
id source;
id destination;
NSString* keyPath;
NSString* bindingPath;
NSString* binding;
NSMutableDictionary *options;
id _source;
id _destination;
NSString* _keyPath;
NSString* _bindingPath;
NSString* _binding;
NSMutableDictionary *_options;
}
@ -55,5 +55,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(BOOL)raisesForNotApplicableKeys;
-(id)multipleValuesPlaceholder;
-(id)noSelectionPlaceholder;
-(id)nullPlaceholder;
@end

View File

@ -22,36 +22,36 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
@implementation _NSBinder (BindingOptions)
-(BOOL)conditionallySetsEditable
{
return [[options objectForKey:NSConditionallySetsEditableBindingOption] boolValue];
return [[_options objectForKey:NSConditionallySetsEditableBindingOption] boolValue];
}
-(BOOL)conditionallySetsEnabled
{
// FIX: needs to read from options
if([source respondsToSelector:@selector(setEditable:)])
if([_source respondsToSelector:@selector(setEditable:)])
return YES;
return NO;
}
-(BOOL)allowsEditingMultipleValues
{
return [[options objectForKey:NSAllowsEditingMultipleValuesSelectionBindingOption] boolValue];
return [[_options objectForKey:NSAllowsEditingMultipleValuesSelectionBindingOption] boolValue];
}
-(BOOL)createsSortDescriptor
{
return [[options objectForKey:NSCreatesSortDescriptorBindingOption] boolValue];
return [[_options objectForKey:NSCreatesSortDescriptorBindingOption] boolValue];
}
-(BOOL)raisesForNotApplicableKeys
{
return [[options objectForKey:NSRaisesForNotApplicableKeysBindingOption] boolValue];
return [[_options objectForKey:NSRaisesForNotApplicableKeysBindingOption] boolValue];
}
-(id)multipleValuesPlaceholder
{
id ret=[options objectForKey:NSMultipleValuesPlaceholderBindingOption];
id ret=[_options objectForKey:NSMultipleValuesPlaceholderBindingOption];
if(!ret)
return NSMultipleValuesMarker;
return ret;
@ -59,7 +59,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(id)noSelectionPlaceholder
{
id ret=[options objectForKey:NSNoSelectionPlaceholderBindingOption];
id ret=[_options objectForKey:NSNoSelectionPlaceholderBindingOption];
if(!ret)
return NSNoSelectionMarker;
return ret;
@ -67,7 +67,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(id)nullPlaceholder
{
id ret=[options objectForKey:NSNullPlaceholderBindingOption];
id ret=[_options objectForKey:NSNullPlaceholderBindingOption];
if(!ret)
return NSNoSelectionMarker;
return ret;
@ -75,14 +75,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(id)valueTransformer
{
id ret=[options objectForKey:NSValueTransformerBindingOption];
id ret=[_options objectForKey:NSValueTransformerBindingOption];
if(!ret)
{
ret=[options objectForKey:NSValueTransformerNameBindingOption];
ret=[_options objectForKey:NSValueTransformerNameBindingOption];
if(!ret)
return nil;
ret=[NSValueTransformer valueTransformerForName:ret];
[options setObject:ret forKey:NSValueTransformerBindingOption];
[_options setObject:ret forKey:NSValueTransformerBindingOption];
}
return ret;
}
@ -110,78 +110,78 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
@implementation _NSBinder
- (id)source {
return [[source retain] autorelease];
return [[_source retain] autorelease];
}
- (void)setSource:(id)value {
if (source != value)
if (_source != value)
{
source = value;
[self setBindingPath:[source _replacementKeyPathForBinding:binding]];
_source = value;
[self setBindingPath:[_source _replacementKeyPathForBinding:_binding]];
}
}
- (id)destination
{
return [[destination retain] autorelease];
return [[_destination retain] autorelease];
}
- (void)setDestination:(id)value
{
if (destination != value)
if (_destination != value)
{
[destination release];
destination = [value retain];
[_destination release];
_destination = [value retain];
}
}
- (NSString*)keyPath {
return [[keyPath retain] autorelease];
return [[_keyPath retain] autorelease];
}
- (void)setKeyPath:(NSString*)value {
if (keyPath != value) {
[keyPath release];
keyPath = [value copy];
if (_keyPath != value) {
[_keyPath release];
_keyPath = [value copy];
}
}
- (NSString*)binding {
return [[binding retain] autorelease];
return [[_binding retain] autorelease];
}
- (void)setBinding:(NSString*)value {
if (binding != value) {
[binding release];
binding = [value copy];
[self setBindingPath:[source _replacementKeyPathForBinding:binding]];
if (_binding != value) {
[_binding release];
_binding = [value copy];
[self setBindingPath:[_source _replacementKeyPathForBinding:_binding]];
}
}
-(id)defaultBindingOptionsForBinding:(id)thisBinding
{
return [source _defaultBindingOptionsForBinding:thisBinding];
return [_source _defaultBindingOptionsForBinding:thisBinding];
}
- (id)options {
return [[options retain] autorelease];
return [[_options retain] autorelease];
}
- (void)setOptions:(id)value {
[options release];
options=[[self defaultBindingOptionsForBinding:binding] mutableCopy];
[_options release];
_options=[[self defaultBindingOptionsForBinding:_binding] mutableCopy];
if(value)
[options setValuesForKeysWithDictionary:value];
[_options setValuesForKeysWithDictionary:value];
}
- (id)bindingPath {
return [[bindingPath retain] autorelease];
return [[_bindingPath retain] autorelease];
}
- (void)setBindingPath:(id)value {
if (bindingPath != value) {
[bindingPath release];
bindingPath = [value copy];
if (_bindingPath != value) {
[_bindingPath release];
_bindingPath = [value copy];
}
}
@ -191,11 +191,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(void)dealloc
{
[self stopObservingChanges];
[keyPath release];
[binding release];
[options release];
[bindingPath release];
[destination retain];
[_keyPath release];
[_binding release];
[_options release];
[_bindingPath release];
[_destination retain];
[super dealloc];
}
@ -210,7 +210,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(NSComparisonResult)compare:(id)other
{
// FIXME: needs to be a compare understanding that 11<20
return [binding compare:[other binding]];
return [_binding compare:[other binding]];
}
-(id)peerBinders
@ -218,15 +218,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
//NSRange numberAtEnd=[binding rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]
// options:NSBackwardsSearch|NSAnchoredSearch];
// FIXME: total hack. assume only one digit at end, 1-9
NSRange numberAtEnd=NSMakeRange([binding length]-1, 1);
if([[binding substringWithRange:numberAtEnd] intValue]==0)
NSRange numberAtEnd=NSMakeRange([_binding length]-1, 1);
if([[_binding substringWithRange:numberAtEnd] intValue]==0)
return nil;
if(numberAtEnd.location==NSNotFound)
return nil;
id baseName=[binding substringToIndex:numberAtEnd.location];
id baseName=[_binding substringToIndex:numberAtEnd.location];
id binders=[[source _allUsedBinders] objectEnumerator];
id binders=[[_source _allUsedBinders] objectEnumerator];
id binder;
id ret=[NSMutableArray array];
while((binder=[binders nextObject])!=nil)
@ -239,7 +239,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(NSString*)description
{
return [NSString stringWithFormat:@"%@: %@", [self className], binding];
return [NSString stringWithFormat:@"%@: %@", [self className], _binding];
}
@end

View File

@ -10,7 +10,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
@interface _NSKVOBinder : _NSBinder
{
id bindingKeyPath;
id _bindingKeyPath;
}
@end

View File

@ -20,12 +20,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
{
//NSLog(@"binding between %@.%@ alias %@ and %@.%@ (%@)", [source className], binding, bindingPath, [destination className], keyPath, self);
[source addObserver:self
forKeyPath:bindingPath
[_source addObserver:self
forKeyPath:_bindingPath
options:0
context:nil];
[destination addObserver:self
forKeyPath:keyPath
[_destination addObserver:self
forKeyPath:_keyPath
options:0
context:nil];
}
@ -33,8 +33,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(void)stopObservingChanges
{
NS_DURING
[source removeObserver:self forKeyPath:bindingPath];
[destination removeObserver:self forKeyPath:keyPath];
[_source removeObserver:self forKeyPath:_bindingPath];
[_destination removeObserver:self forKeyPath:_keyPath];
NS_HANDLER
NS_ENDHANDLER
}
@ -51,7 +51,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
peers=[peers sortedArrayUsingSelector:@selector(compare:)];
id values=[peers valueForKeyPath:@"realDestinationValue"];
int i;
id pattern=[[[options objectForKey:@"NSDisplayPattern"] mutableCopy] autorelease];
id pattern=[[[_options objectForKey:@"NSDisplayPattern"] mutableCopy] autorelease];
if(pattern)
{
for(i=0; i<[peers count]; i++)
@ -65,7 +65,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
else if([[values lastObject] isKindOfClass:[NSNumber class]])
{
BOOL ret;
if([binding isEqual:@"hidden"])
if([_binding isEqual:@"hidden"])
{
ret=NO;
for(i=0; i<[peers count]; i++)
@ -94,19 +94,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
return pattern;
}
else
return [destination valueForKeyPath:keyPath];
return [_destination valueForKeyPath:_keyPath];
}
-(id)_realDestinationValue
{
return [destination valueForKeyPath:keyPath];
return [_destination valueForKeyPath:_keyPath];
}
-(void)syncUp
{
NS_DURING
if([self destinationValue])
[source setValue:[self destinationValue] forKeyPath:bindingPath];
[_source setValue:[self destinationValue] forKeyPath:_bindingPath];
NS_HANDLER
if([self raisesForNotApplicableKeys])
[localException raise];
@ -118,14 +118,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
{
[self stopObservingChanges];
if(object==source)
if(object==_source)
{
//NSLog(@"bind event from %@.%@ alias %@ to %@.%@ (%@)", [source className], binding, bindingPath, [destination className], keyPath, self);
[destination setValue:[source valueForKeyPath:bindingPath]
forKeyPath:keyPath];
[_destination setValue:[_source valueForKeyPath:_bindingPath]
forKeyPath:_keyPath];
}
else if(object==destination)
else if(object==_destination)
{
//NSLog(@"bind event from %@.%@ to %@.%@ alias %@ (%@)", [destination className], keyPath, [source className], binding, bindingPath, self);
id newValue=[self destinationValue];
@ -152,19 +152,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
}
if([self conditionallySetsEditable])
[source setEditable:editable];
[_source setEditable:editable];
if([self conditionallySetsEnabled])
[source setEnabled:editable];
[_source setEnabled:editable];
[source setValue:newValue
forKeyPath:bindingPath];
[_source setValue:newValue
forKeyPath:_bindingPath];
if(isPlaceholder && [source respondsToSelector:@selector(_setCurrentValueIsPlaceholder:)])
[source _setCurrentValueIsPlaceholder:YES];
if(isPlaceholder && [_source respondsToSelector:@selector(_setCurrentValueIsPlaceholder:)])
[_source _setCurrentValueIsPlaceholder:YES];
}
else
{
NSLog(@"unexpected change notification for object %@ (src %@, dest %@)", object, source, destination);
NSLog(@"unexpected change notification for object %@ (src %@, dest %@)", object, _source, _destination);
}
[self startObservingChanges];

View File

@ -11,9 +11,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
@interface _NSMultipleValueBinder : _NSBinder
{
NSArray* rowValues;
NSString* arrayKeyPath;
NSString* valueKeyPath;
NSArray* _rowValues;
NSString* _arrayKeyPath;
NSString* _valueKeyPath;
}
-(void)applyToCell:(id)cell inRow:(int)row;
-(void)applyFromCell:(id)cell inRow:(int)row;

View File

@ -33,58 +33,58 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
- (NSArray *)rowValues
{
return [[rowValues retain] autorelease];
return [[_rowValues retain] autorelease];
}
- (void)setRowValues:(NSArray *)value
{
if (rowValues != value)
if (_rowValues != value)
{
[rowValues release];
rowValues = [value retain];
[_rowValues release];
_rowValues = [value retain];
}
}
-(void)applyToObject:(id)object inRow:(int)row keyPath:(id)path
{
[object setValue:[[rowValues objectAtIndex:row] valueForKeyPath:valueKeyPath] forKey:path];
[object setValue:[[_rowValues objectAtIndex:row] valueForKeyPath:_valueKeyPath] forKey:path];
}
-(void)applyToObject:(id)object inRow:(int)row
{
[self applyToObject:object inRow:row keyPath:bindingPath];
[self applyToObject:object inRow:row keyPath:_bindingPath];
}
-(void)applyToCell:(id)cell inRow:(int)row
{
[self applyToObject:cell inRow:row keyPath:bindingPath];
[self applyToObject:cell inRow:row keyPath:_bindingPath];
}
-(void)applyFromObject:(id)object inRow:(int)row keyPath:(id)keypath
{
[[rowValues objectAtIndex:row] setValue:[object valueForKeyPath:keypath]
forKeyPath:valueKeyPath];
[[_rowValues objectAtIndex:row] setValue:[object valueForKeyPath:keypath]
forKeyPath:_valueKeyPath];
}
-(void)applyFromObject:(id)object inRow:(int)row
{
[self applyFromObject:object inRow:row keyPath:bindingPath];
[self applyFromObject:object inRow:row keyPath:_bindingPath];
}
-(void)applyFromCell:(id)cell inRow:(int)row
{
[self applyFromObject:cell inRow:row keyPath:bindingPath];
[self applyFromObject:cell inRow:row keyPath:_bindingPath];
}
-(unsigned)count
{
return [rowValues count];
return [_rowValues count];
}
-(id)objectAtIndex:(unsigned)row
{
return [[rowValues objectAtIndex:row] valueForKeyPath:valueKeyPath];
return [[_rowValues objectAtIndex:row] valueForKeyPath:_valueKeyPath];
}
#pragma mark -
@ -98,11 +98,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
In case the last component is actually a parameter to an operator,
we have to take the last two components.
*/
id components=[keyPath componentsSeparatedByString:@"."];
id components=[_keyPath componentsSeparatedByString:@"."];
if([components count]==1)
{
valueKeyPath=@"self";
arrayKeyPath=[components lastObject];
_valueKeyPath=@"self";
_arrayKeyPath=[components lastObject];
}
else
{
@ -110,17 +110,17 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
if([secondToLast hasPrefix:@"@"])
{
valueKeyPath=keyPath;
arrayKeyPath=@"self";
_valueKeyPath=_keyPath;
_arrayKeyPath=@"self";
}
else
{
valueKeyPath=[components lastObject];
arrayKeyPath= [keyPath substringToIndex:[keyPath length]-[valueKeyPath length]-1];
_valueKeyPath=[components lastObject];
_arrayKeyPath= [_keyPath substringToIndex:[_keyPath length]-[_valueKeyPath length]-1];
}
}
[valueKeyPath retain];
[arrayKeyPath retain];
[_valueKeyPath retain];
[_arrayKeyPath retain];
}
-(BOOL)allowsEditingForRow:(int)row
@ -131,8 +131,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(void)dealloc
{
[arrayKeyPath release];
[valueKeyPath release];
[_arrayKeyPath release];
[_valueKeyPath release];
[self setRowValues:nil];
[super dealloc];
}
@ -140,11 +140,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(void)startObservingChanges
{
NS_DURING
[destination addObserver:self forKeyPath:arrayKeyPath options:0 context:destination];
if(![valueKeyPath hasPrefix:@"@"])
[rowValues addObserver:self
toObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [rowValues count])]
forKeyPath:valueKeyPath
[_destination addObserver:self forKeyPath:_arrayKeyPath options:0 context:_destination];
if(![_valueKeyPath hasPrefix:@"@"])
[_rowValues addObserver:self
toObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [_rowValues count])]
forKeyPath:_valueKeyPath
options:0
context:nil];
NS_HANDLER
@ -154,11 +154,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(void)stopObservingChanges
{
NS_DURING
[destination removeObserver:self forKeyPath:arrayKeyPath];
if(![valueKeyPath hasPrefix:@"@"])
[rowValues removeObserver:self
fromObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [rowValues count])]
forKeyPath:valueKeyPath];
[_destination removeObserver:self forKeyPath:_arrayKeyPath];
if(![_valueKeyPath hasPrefix:@"@"])
[_rowValues removeObserver:self
fromObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [_rowValues count])]
forKeyPath:_valueKeyPath];
NS_HANDLER
NS_ENDHANDLER
}
@ -170,11 +170,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
- (void)observeValueForKeyPath:(NSString *)kp ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if(object==source)
if(object==_source)
{
//NSLog(@"bind event from %@.%@ alias %@ to %@.%@ (%@)", [source className], binding, bindingPath, [destination className], keyPath, self);
}
else if(context==destination)
else if(context==_destination)
{
[self stopObservingChanges];
@ -182,27 +182,27 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
[self updateRowValues];
if([source respondsToSelector:@selector(_boundValuesChanged)])
[source _boundValuesChanged];
if([_source respondsToSelector:@selector(_boundValuesChanged)])
[_source _boundValuesChanged];
[self startObservingChanges];
}
else if(context==nil)
{
if([source respondsToSelector:@selector(reloadData)])
[source reloadData];
if([source respondsToSelector:@selector(tableView)])
[[source tableView] reloadData];
if([_source respondsToSelector:@selector(reloadData)])
[_source reloadData];
if([_source respondsToSelector:@selector(tableView)])
[[_source tableView] reloadData];
if([destination respondsToSelector:@selector(_selectionMayHaveChanged)])
[destination performSelector:@selector(_selectionMayHaveChanged)];
if([_destination respondsToSelector:@selector(_selectionMayHaveChanged)])
[_destination performSelector:@selector(_selectionMayHaveChanged)];
}
}
-(id)defaultBindingOptionsForBinding:(id)thisBinding
{
return [[source dataCell] _defaultBindingOptionsForBinding:thisBinding];
return [[_source dataCell] _defaultBindingOptionsForBinding:thisBinding];
}
-(void)bind
@ -212,15 +212,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
[self syncUp];
[self startObservingChanges];
if([self createsSortDescriptor] && [binding isEqual:@"value"])
if([self createsSortDescriptor] && [_binding isEqual:@"value"])
{
[source setSortDescriptorPrototype:[[[NSSortDescriptor alloc] initWithKey:valueKeyPath
[_source setSortDescriptorPrototype:[[[NSSortDescriptor alloc] initWithKey:_valueKeyPath
ascending:NO] autorelease]];
}
if([source respondsToSelector:@selector(_establishBindingsWithDestinationIfUnbound:)])
if([_source respondsToSelector:@selector(_establishBindingsWithDestinationIfUnbound:)])
{
[source performSelector:@selector(_establishBindingsWithDestinationIfUnbound:)
withObject:destination
[_source performSelector:@selector(_establishBindingsWithDestinationIfUnbound:)
withObject:_destination
afterDelay:0.0];
}
}
@ -240,7 +240,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(void)updateRowValues
{
id value=[destination valueForKeyPath:arrayKeyPath];
id value=[_destination valueForKeyPath:_arrayKeyPath];
if(![value respondsToSelector:@selector(objectAtIndex:)])
value=[[[_NSMultipleValueWrapperArray alloc] initWithObject:value] autorelease];
[self setRowValues:value];
@ -258,9 +258,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
@implementation _NSTableViewContentBinder
-(void)startObservingChanges
{
NSParameterAssert([source isKindOfClass:[NSTableView class]]);
[destination addObserver:self
forKeyPath:keyPath
NSParameterAssert([_source isKindOfClass:[NSTableView class]]);
[_destination addObserver:self
forKeyPath:_keyPath
options:NSKeyValueObservingOptionNew
context:nil];
}
@ -268,26 +268,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(void)stopObservingChanges
{
NS_DURING
[destination removeObserver:self forKeyPath:keyPath];
[_destination removeObserver:self forKeyPath:_keyPath];
NS_HANDLER
NS_ENDHANDLER
}
-(void)syncUp
{
[source performSelector:@selector(reloadData)
[_source performSelector:@selector(reloadData)
withObject:nil
afterDelay:0.0];
[source reloadData];
[_source reloadData];
}
- (void)observeValueForKeyPath:(NSString *)kp ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
[self stopObservingChanges];
if(object==destination)
if(object==_destination)
{
[source _boundValuesChanged];
[_source _boundValuesChanged];
}
[self startObservingChanges];
@ -306,7 +306,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(unsigned)numberOfRows
{
return [[destination valueForKeyPath:keyPath] count];
return [[_destination valueForKeyPath:_keyPath] count];
}
@end

View File

@ -42,6 +42,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
// unbinds all bindings used; should be called in -dealloc
-(void)_unbindAllBindings;
// the currently set value is a placeholder and should be displayed accordingly
-(id)_setCurrentValueIsPlaceholder:(BOOL)isPlaceholder;
@end
APPKIT_EXPORT NSString* NSObservedObjectKey;

View File

@ -418,19 +418,20 @@ void objc_setProperty (id self, SEL _cmd, size_t offset, id value, BOOL isAtomic
char *sel=__builtin_alloca(selLen+1);
strcpy(sel, origName);
sel[selLen-1]='\0';
if(sel[0]=='_')
sel+=4;
else
sel+=3;
sel+=3;
sel[0]=tolower(sel[0]);
NSString *key=[[NSString alloc] initWithCString:sel];
[self willChangeValueForKey:key];
void *buffer=(void*)self+offset;
id oldValue=*(id*)buffer;
if(shouldCopy)
*(id*)buffer=[value copy];
else
*(id*)buffer=[value retain];
[oldValue release];
[self didChangeValueForKey:key];
[key release];

View File

@ -63,7 +63,7 @@ id NSAllocateObject(Class class,unsigned extraBytes,NSZone *zone) {
result=calloc(1,class->instance_size+extraBytes);
result->isa=class;
if(!object_cxxConstruct(result, object->isa))
if(!object_cxxConstruct(result, result->isa))
{
free(result);
result=nil;