You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
2.3 KiB
Objective-C
136 lines
2.3 KiB
Objective-C
#import "Test.h"
|
|
|
|
// Checks using non-portable APIs
|
|
#ifdef GNUSTEP_RUNTIME
|
|
void check_retain_count(id obj, size_t rc)
|
|
{
|
|
assert(object_getRetainCount_np(obj) == rc);
|
|
}
|
|
void check_autorelease_count(id obj, size_t rc)
|
|
{
|
|
assert(objc_arc_autorelease_count_for_object_np(obj) == rc);
|
|
}
|
|
#else
|
|
void check_retain_count(id obj, size_t rc)
|
|
{
|
|
}
|
|
void check_autorelease_count(id obj, size_t rc)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
id __weak var;
|
|
|
|
@interface ARC : Test @end
|
|
@implementation ARC
|
|
- (id __autoreleasing)loadWeakAutoreleasing
|
|
{
|
|
return var;
|
|
}
|
|
- (id)loadWeak
|
|
{
|
|
return var;
|
|
}
|
|
- (void)setWeakFromWeak: (id __weak)anObject
|
|
{
|
|
var = anObject;
|
|
anObject = nil;
|
|
}
|
|
- (void)setWeak: (id)anObject
|
|
{
|
|
var = anObject;
|
|
}
|
|
@end
|
|
|
|
@interface CheckDealloc : Test
|
|
@end
|
|
@implementation CheckDealloc
|
|
{
|
|
BOOL *flag;
|
|
}
|
|
- (id)initWithFlag: (BOOL*)aFlag
|
|
{
|
|
flag = aFlag;
|
|
*flag = NO;
|
|
return self;
|
|
}
|
|
- (void)dealloc
|
|
{
|
|
*flag = YES;
|
|
}
|
|
@end
|
|
|
|
static __weak id weakRef;
|
|
|
|
@interface CheckDeallocWeakRef : Test
|
|
@end
|
|
@implementation CheckDeallocWeakRef
|
|
- (void)dealloc
|
|
{
|
|
weakRef = self;
|
|
}
|
|
@end
|
|
|
|
|
|
int main(void)
|
|
{
|
|
ARC *obj = [ARC new];
|
|
BOOL f1;
|
|
BOOL f2;
|
|
// Check that storing weak references works.
|
|
{
|
|
id o1 = [[CheckDealloc new] initWithFlag: &f1];
|
|
id o2 = [[CheckDealloc new] initWithFlag: &f2];
|
|
[obj setWeak: o1];
|
|
assert([obj loadWeak] == o1);
|
|
[obj setWeakFromWeak: o2];
|
|
assert([obj loadWeak] == o2);
|
|
@autoreleasepool
|
|
{
|
|
id __autoreleasing o2a = [obj loadWeakAutoreleasing];
|
|
assert(o2a == o2);
|
|
}
|
|
}
|
|
assert(f1);
|
|
assert(f2);
|
|
assert([obj loadWeak] == nil);
|
|
@autoreleasepool
|
|
{
|
|
id __autoreleasing o1a;
|
|
{
|
|
id o1 = [[CheckDealloc new] initWithFlag: &f1];
|
|
assert(!f1);
|
|
[obj setWeak: o1];
|
|
assert([obj loadWeak] == o1);
|
|
o1a = [obj loadWeakAutoreleasing];
|
|
assert(o1a == o1);
|
|
check_autorelease_count(o1a, 1);
|
|
check_retain_count(o1a, 1);
|
|
}
|
|
assert(o1a == [obj loadWeak]);
|
|
}
|
|
assert(f1);
|
|
assert([obj loadWeak] == nil);
|
|
// Try to trigger an objc_moveWeak call
|
|
{
|
|
id o1 = [Test new];
|
|
{
|
|
id __weak x = o1;
|
|
var = x;
|
|
}
|
|
}
|
|
assert([obj loadWeak] == nil);
|
|
// Now check what happens with a constant string in a weak variable.
|
|
{
|
|
id x = @"foo";
|
|
[obj setWeak: x];
|
|
}
|
|
assert([obj loadWeak] != nil);
|
|
// Check setting weak references during dealloc
|
|
{
|
|
[CheckDeallocWeakRef new];
|
|
}
|
|
assert(weakRef == nil);
|
|
return 0;
|
|
}
|