2010-07-27 33 views
8

ile ben aşağıdaki yöntemi vardır:iphone - performSelectorOnMainThread dönüş değeri

- (NSMutableArray *)getElements:(NSString *)theURL; 

Ve ben dönüş değeri elde böylece performSelectorOnMainThread kullanarak o yöntemi çağırmak için bir yol olup olmadığını öğrenmek istedi. Şimdiye kadar birlikte denedim:

myArray = [object performSelectorOnMainThread:@selector(getElements:) 
            withObject:url waitUntilDone:YES]; 

ama performSelectorOnMainThread geçersiz döndürür çünkü, çalışmıyor. Bunu nasıl çözebilirim?

cevap

12

Çok parçalı bir ortama hoş geldin arkadaşım.

Bir örnek değişkeninde dönüş değeri saklamak veya withObject parametre üzerinden referans olarak bir nesne geçer gerekir:

NSMutableDictionary *myDict; 

[object performSelectorOnMainThread:@selector(getElements:) 
            withObject:&myDict waitUntilDone:YES]; 

Yöntemin prototip şimdi şu şekilde görünmelidir:

- (void)getElements:(NSMutableDictionary **)objects; 
+5

Bu, "NSMutableDictionary **" türünde bir değerle 'id' türünde bir parametre başlatılamıyor. "" – eodabash

3

Doğrudan yapamazsınız, çünkü, söylediğiniz gibi, bu yöntem geçersiz sayılır. Bu nedenle, örneğin bir NSString yerine bir NSDictionary geçirerek ve sonuçta sözlüğün sizin için sözlükte saklanmasını sağlayarak, bir değer geri almanın başka bir yolunu ayarlamanız gerekir.

2

Bunu yakın zamanda uygulamak zorundaydık. tüm nesneleri bunu böylece NSObject bir kategori eklemek için Büyük adayı:

@implementation NSObject (CallSelectorWithObjectOnMainThread) 
- (id)resultFromSelectorOnMainThread:(SEL)selector object:(id)object { 
    NSMutableDictionary *resultDictionary = [NSMutableDictionary dictionaryWithCapacity:1]; 
    NSMutableDictionary *callDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:resultDictionary, @"ResultDictionary", NSStringFromSelector(selector), @"Selector", nil]; 
    if(object) [callDict setValue:object forKey:@"Object"]; 
    [self performSelectorOnMainThread:@selector(callObject:) withObject:callDict waitUntilDone:YES]; 
    return [resultDictionary objectForKey:@"Result"]; 
} 

- (void)callObject:(NSMutableDictionary *)info { 
    id result; 
    SEL selector = NSSelectorFromString([info objectForKey:@"Selector"]); 
    id object = [info objectForKey:@"Object"]; 
    NSMutableDictionary *resultDictionary = [info objectForKey:@"Dictionary"]; 
    if(object) 
    result = [self performSelector:selector withObject:object]; 
    else 
    result = [self performSelector:selector]; 
    if(result) 
    [resultDictionary setValue:result forKey:@"Result"]; 
} 
@end 
+0

+1 Bu Colin için teşekkürler. Kullandıktan sonra bir çift kusur buldum: callDict NSMutableDictionary ile başlatılması gerekiyor ve callObject bir NSMutableDictionary yöntemi argümanına sahip olması gerekiyor. – TPoschel

+0

@TPoschel Teşekkürler! – Colin

2

Ben herhangi bir iş parçacığı dönüş değeri ile zaman uyumsuz engelleme çağrısı için evrensel çözüm, ana sadece. withObject: waitUntilDone: performSelectorOnMainThread gibi ana iş parçacığı için Bu örnek

__block id result = nil; 
NSOperationQueue* targetQueue = [NSOperationQueue* mainQueue]; 
// targetQueue is main thread, but it may be queue on any thread. 

[targetQueue addBlockOperation:^{ 
    // performs on target thread. 
    result = [someObject someSelector]; 
}]; 

// wait until operations on targetQueue will finished. 
[targetQueue waitUntilAllOperationsAreFinished]; 

// result is ready here. 

Ben sadece ARC ortamında bu tekniği kullanılır.