如果对象被释放,则弱属性应该指向零,但在这种情况下,弱属性似乎保留了对象。考虑以下情况:
@interface SillyObject : NSObject
@property (nonatomic, assign) NSInteger val;
-(void)printVal;
@end
@implementation SillyObject
-(void)printVal
{
NSLog(@"%d", self.val);
}
@end
-(void)saveReference
{
SillyObject* s = [SillyObject new];
s.val = 100;
[[ObjectCache sharedInstance] addWeakRef:s callback:^(NSString* junk) {
[s printVal];
}];
}callSillyObjectBlocks循环所有添加到缓存中的对象,并调用对应的块(参见下面)
-(void)callDeadObject
{
[self saveReference];
[[ObjectCache sharedInstance] callSillyObjectBlocks];
}现在,saveReference退出,SillyObject应该被解除分配,但是它没有,弱引用也不是零。
缓存的相关实现细节:
typedef void (^Callback)(NSString* junk);
@interface CacheSlot : NSObject
@property (nonatomic, copy) Callback callback;
@property (nonatomic, weak) id source;
// More irrelevant properties.
-(instancetype)initWithRef:(__weak id)obj callback:(Callback)cb;
@end
@implementation CacheSlot
@synthesize callback, source;
-(instancetype)initWithRef:(__weak id)obj callback:(Callback)cb
{
self = [super init];
if(self)
{
self.callback = cb;
self.source = obj;
}
return self;
}
@end
@interface ObjectCache()
// This array contains CacheSlot objects
@property (nonatomic, strong) NSMutableArray* savedObjects;
@end
// Implementation.
-(void)addWeakRef:(id)obj callback:(Callback)block
{
__weak id src = obj;
[self.savedObjects addObject:[[CacheSlot alloc] initWithRef:src callback:block]];
}
-(void)callSillyObjectBlocks
{
for(CacheSlot* slot in self.savedObjects)
{
if(slot.source)
{
slot.callback(@"Whatever!");
}
else
{
// Remove the slot from cache
}
}
}最初调用saveReference应该创建一个临时对象,该对象在函数退出时立即被释放(如果我调用addWeakRef:nil,它就会这样做)。
在调用saveReference之后,我运行callSillyObjectBlocks,添加的对象的相应块不应该被调用,但是它是用对象的值被调用的。输出:
100发布于 2013-10-04 13:05:43
每当您有一个从块外部引用变量的块时,您也需要声明它是弱的。否则你会得到强有力的推荐信。所以应该是:
-(void)saveReference
{
SillyObject* s = [SillyObject new];
s.val = 100;
SillyObject * __weak weakSilly = s;
[[ObjectCache sharedInstance] addWeakRef:s callback:^(NSString* junk) {
[weakSilly printVal];
}];
}同时,您可以通过从其他几个位置删除__weak来简化代码,因为它们只会影响方法参数,在相关的时间内不会保留实例:
-(instancetype)initWithRef:(id)obj callback:(Callback)cb {
...
}
-(void)addWeakRef:(id)obj callback:(Callback)block
{
[self.savedObjects addObject:[[CacheSlot alloc] initWithRef:obj callback:block]];
}https://stackoverflow.com/questions/19181732
复制相似问题