iOS Delegate使用assign修饰崩溃(应使用weak
2022-05-24 本文已影响0人
心猿意码_
问题描述:
Delegate
使用assign
修饰是产生崩溃。
原因:
-
weak:
指明该对象并不负责保持delegate这个对象,delegate的销毁由外部控制。当delegate
指向的对象销毁后,自动delegate = nil
。 -
assign:
是指针赋值,不对引用计数操作,使用之后如果没有置为nil,可能就会产生野指针。即便delegate
指向的对象销毁了,delegate
中依然会保存之前对象的地址,即delegate
成为了一个野指针。
为什么用weak
不用assign
?
-
assign
是指针赋值,不操作引用计数,delegate
用完后如果没有设置为nil
,有可能产生野指针。 -
weak
指向的delegate
一旦用完,自动就nil
了,不会产生野指针。
示例代码如下:
Book
文件
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol TestlDelegate <NSObject>
@optional
-(void)testDelegate:(NSString *)str;
@end
@interface Book : NSObject
@property (nonatomic,assign) id <TestlDelegate> delegate;
-(void)test;
@end
NS_ASSUME_NONNULL_END
#import "Book.h"
@implementation Book
-(void)test{
if(self.delegate && [self.delegate respondsToSelector:@selector(testDelegate:)]){
[self.delegate testDelegate:@"我是一条测试回调"];
}
}
@end
Store
文件
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Store : NSObject
@end
NS_ASSUME_NONNULL_END
#import "Store.h"
@interface Store ()
@end
@implementation Store
@end
ViewController
中调用
#import "ViewController.h"
#import "Book.h"
#import "Store.h"
@interface ViewController ()<TestlDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor orangeColor];
Book *book = [[Book alloc] init];
{ //从作用域出去后store就会释放,此时delegate并未释放或置为nil,成为了一个野指针,所以再调用 [book test]; 时崩溃
Store *store = [[Store alloc] init];
book.delegate = store;
}
[book test];
}
@end
总结:store
从作用域出去后,store
就会释放,此时delegate
并未释放或置为nil
,成为了一个野指针,所以再调用 [book test];
时崩溃,将assign
改为weak
则可解决此崩溃问题。