问题
Message *m = [msg retain];
dispatch_queue_t queue = _handle_queue;
__block ProtocolDriver* blockSelf = self;
dispatch_async(queue, ^{
if (blockSelf.protocol_delegate && [blockSelf.protocol_delegate respondsToSelector:@selector(onReceive:)]) {
[blockSelf.protocol_delegate onReceive:m];
}
});
I have a MRC objective-c file, which need run some code in block asynchronously.
But I thought the blockself
is not safe since it is not weak pointer, Should I change it to true weak pointer.
@interface WeakPtr : NSObject
@property (nonatomic, weak) id realObj;
@property (nonatomic, assign) bool released;
@end
@implementation WeakPtr
@end
set the released when the MRC-object is dealloced, and test it in block
@property (nonatomic, retain) WeakPtr* selfPtr;
- (id)init{
...
self.selfPtr = [[[WeakPtr alloc] init] autorelease];
self.selfPtr.realObj = self;
}
- (void)dealloc
{
...
self.selfPtr.released = true;
}
-(void)pump: (Message *)msg
{
Message *m = [msg retain];
dispatch_queue_t queue = _handle_queue;
__block WeakPtr* weakSelf = self.selfPtr;
dispatch_async(queue, ^{
if (!weakSelf.released && [weakSelf.protocol_delegate respondsToSelector:@selector(onReceive:)]) {
[weakSelf.protocol_delegate onReceive:m];
}
});
}
回答1:
Yes, definitely.
1) make a ARC weak pointer wrapper class.
@interface WeakPtr : NSObject
@property (nonatomic, weak) id realObj;
@end
@implementation WeakPtr
@end
2) use the ARC weak pointer wrapper in MRC to wrap the strong pointer.
-(void)pump: (Message *)msg
{
Message *m = [msg retain];
dispatch_queue_t queue = _handle_queue;
WeakPtr* weakPtr = [WeakPtr new];
weakPtr.realObj = self;
dispatch_async(queue, ^{
if ([weakPtr.realObj.protocol_delegate respondsToSelector:@selector(onReceive:)]) {
[weakPtr.realObj.protocol_delegate onReceive:m];
}
[weakPtr release];
});
}
Another option is -fobj-weak
compiler flag.
回答2:
Short answer: You can't. The weak
qualifier is a feature of ARC. In MRC, the type is assign, and it's equivalent to ARC's unsafe_unretained
type.
MRC does not have an auto-niling weak type.
Edit:
Ok, perhaps "you can't" was too strong. Better to say:
MRC doesn't support auto niling weak references and you would have to handle it with app-level code, or a library that does it for you.
来源:https://stackoverflow.com/questions/40966421/how-to-make-weak-self-in-mrc