@interface URLClass : NSObject
{
id target;
SEL funObj;
}
+ (URLClass *)sharedInstance;
-(void)theBigFunction:(SEL)func :(id)target;
@property (nonatomic,retain) SEL funObj;
#import "URLClass.h"
static URLClass *instance = NULL;
@implementation URLClass
{
NSMutableData *webData;
}
- (id)init
{
if ( self = [super init] )
{
}
return self;
}
+ (URLClass *)sharedInstance
{
@synchronized([URLClass class])
{
if (!instance)
instance = [[super alloc] init];
return instance;
}
return nil;
}
-(void)theBigFunction:(SEL)func :(id)targetObj{
funObj =func;
target=targetObj;
NSURL *URL = [NSURL URLWithString:@"urlString"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
if( connection )
{
webData = [NSMutableData data] ;
}
else
{
NSLog(@"theConnection is NULL");
}
}
-(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return YES;
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[webData setLength: 0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[webData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"ERROR with theConenction");
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error;
id jsonObj = [NSJSONSerialization JSONObjectWithData:webData options:0 error:&error];
if (jsonObj!=nil && error==nil) {
if ([jsonObj isKindOfClass:[NSDictionary class]]) {
NSDictionary *dic=(NSDictionary*)jsonObj;
NSLog(@"DIC jsonObj %@ ",dic);
NSArray *array=[dic objectForKey:@"items"];
NSLog(@"array jsonObj %@ %d",array,[array count]);
}else if ([jsonObj isKindOfClass:[NSArray class]]) {
NSArray *arr=(NSArray*)jsonObj;
NSLog(@"arr jsonObj %@ ",arr);
}
}
[target performSelector:funObj];
// Not gEtting called the aboue line
// performSelector可能会导致泄漏,因为它的选择器是上面一行中的未知警告 }
当我计划在下面的行中执行来自任何类的代码。它不被称为。
-(void)loginPress:(id)sender{
URLClass *rlOBJ=[URLClass sharedInstance];
[rlOBJ theBigFunction:@selector(upd_Handler:) :self];
}
- (void) upd_Handler: (id) value{
NSLog( @"Seccess");
}
答案 0 :(得分:15)
现代方法是让您的类接受完成块而不是目标/选择器。然后你不必插入一堆丑陋的编译器抑制行,你就会获得更大的灵活性。
答案 1 :(得分:9)
以下是[target performSelector:selector withObject:object];
的完整替代以避免警告。使用以下任一替换:
[NSObject target:target performSelector:selector withObject:object];
@interface NSObject (NSPerformSelector)
+ (id)target:(id)target performSelector:(SEL)selector;
+ (id)target:(id)target performSelector:(SEL)selector withObject:(id)object;
+ (id)target:(id)target performSelector:(SEL)selector withObject:(id)object1 withObject2:(id)object2;
@end
@implementation NSObject (NSPerformSelector)
+ (id)target:(id)target performSelector:(SEL)selector {
IMP imp = [target methodForSelector:selector];
id (*func)(id, SEL) = (void *)imp;
return func(target, selector);
}
+ (id)target:(id)target performSelector:(SEL)selector withObject:(id)object {
IMP imp = [target methodForSelector:selector];
id (*func)(id, SEL, id) = (void *)imp;
return func(target, selector, object);
}
+ (id)target:(id)target performSelector:(SEL)selector withObject:(id)object1 withObject2:(id)object2 {
IMP imp = [target methodForSelector:selector];
id (*func)(id, SEL, id, id) = (void *)imp;
return func(target, selector, object1, object2);
}
@end
答案 2 :(得分:8)
只需使用[sender performSelector:selector withObject:object afterDelay:0];
这将删除警告,代码将正常运行。
答案 3 :(得分:2)
这是一个警告,而不是错误。您的代码仍然有用。
当你调用一个选择器并且编译器无法告诉选择器是什么时,它无法判断被调用的方法是否将获取传递的对象的所有权,或者释放它,或者其他什么。因此,ARC无法确定是否可以正确处理参数的内存管理。
您应该能够在编译器指令中包含performSelector调用以禁用该警告。然后,您将负担确保被调用的方法不会对传递给它的对象保持任何强引用,或者释放该对象。
答案 4 :(得分:2)
您无需在bigFunction中传递成功方法。相反,你应该使用完成块,如[Wil Shipley] [1]
所建议的那样以下是NSURLConnection发出异步请求并返回的示例;响应,数据和错误;如果有的话。将来你应该参考文档。
NSURLConnection类参考 https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/index.html
+ (void)sendAsynchronousRequest:(NSURLRequest *)request
queue:(NSOperationQueue *)queue
completionHandler:(void (^)(NSURLResponse *response,
NSData *data,
NSError *connectionError))handler
你可以像这样重写你的bigFunction方法 -
- (void)bigFunctionWithYourInputData:(NSDictionary*)userInfo withCompletionHandler:(void(^)(NSData* data, NSError* error))completionHandler {
NSURL *theUrl = [NSURL URLWithString:[userInfo objectForKey:@"url"];
NSURLRequest *req = [NSURLRequest requestWithURL:theUrl];
[NSURLConnection sendAsynchronousRequest:req queue:nil completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!connectionError) {
//do what you want with your data
NSLog(@"response :%@", response);
NSLog(@"data :%@", data);
//pass to your completion handler
if(completionHandler) {
completionHandler(data, nil);
}
} else {
//something went wrong
NSLog(@"Got the error with code :%ld", (long)connectionError.code);
//pass to your completion handler
if(completionHandler) {
completionHandler(nil, error);
}
}
}];
}
然后你会通过你的单身人士在其他地方实现它 -
[URLClass sharedInstance] bigFunctionWithYourInputData:_someDictionaryData withCompletionHandler:^(NSData* data, NSError* error) {
if (!error) {
//success
NSLog(@"returned the data:%@", data);
} else {
//handler the error somehow
}
}];