Pertanyaan Compiler memberikan peringatan pada performSelectorOnMainThread: @selector (delegateMethod)


Saya memiliki NSOperation yang membungkus beberapa fungsi layanan web. NSOperation memiliki delegasi yang akan dikirim ketika operasi selesai.

Karena NSOperation tinggal di utas yang berbeda, saya harus melakukan panggilan seperti ini:

[delegate performSelectorOnMainThread:@selector(getDealersIDSuccess:) withObject:result waitUntilDone:YES];

Ini bekerja dengan baik, tetapi itu memberi saya peringatan:

PERINGATAN:   '-performSelectorOnMainThread: withObject: waitUntilDone:'   tidak ditemukan dalam protokol (s)

Saya sepenuhnya setuju dengan compiler yang satu ini, ia melihat seorang delegasi, ia memeriksa protokol, ia tidak menemukan deklarasi dari metode performSelector.

Pertanyaan saya adalah: dapatkah saya menghapus peringatan dengan membuat panggilan ini dengan cara yang berbeda?

Dua dugaanku adalah aku bisa (1) menulis metode yang disebut

- (void) callDelegateMethodOnMainThred {
    [delegate getDealersIDSuccess:result]
}

dan sebut itu melalui performSelectorOnMainThread, tetapi saya menemukan solusi itu menjadi rumit dan ekstra, sulit dibaca, melangkah di atas delegasi.

Solusi kedua adalah mengirimkan delegasi ke tipe objek orang tua saya di dalam pemilih, tetapi itu sekadar gila dan bertentangan dengan pola enkapsulasi delegasi.

Saya akan sangat menghargai solusi ketiga dari seseorang dengan pemahaman bahasa yang lebih baik :)

Terima kasih sebelumnya.

EDIT: Menambahkan pernyataan delegasi:

id <ISDealersIDDelegate> delegate;

Saya menyatakan delegasi saya sebagai id. Delegasi itu sendiri memperluas UIViewController.

Saya dapat melihat bahwa mendeklarasikannya NSObject akan berhasil.


8
2017-12-21 12:41


asal


Jawaban:


performSelectorOnMainThread:withObject:waitUntilDone: metode dideklarasikan di NSObject kelas. Jika objek delegasi Anda mewarisi dari NSObject Anda dapat mendeklarasikannya sebagai

NSObject<MyDelegateProtocol> *delegate;

Jadi compiler akan tahu bahwa delegate merespon metode NSObject dan tidak akan mengeluarkan peringatan.


18
2017-12-21 12:57



Bahkan mungkin solusi yang lebih baik tidak memanggil performSelectorOnMainThread: pada delegasi atau implementasi protokol lainnya. Jadikan tanggung jawab delegasi / penerima untuk menentukan apakah perlu melakukan hal-hal pada utas utama.

[delegate performSelector:@selector(delegateAction:)
               withObject:actionData];

Mendelegasikan implementasi

- (void)delegateAction:(NSData*)actionData
{
    [self performSelectorOnMainThread:@selector(updateUIForAction:)
                           withObject:actionData
                        waitUntilDone:NO];
}

- (void)updateUIForAction:(NSData*)actionData
{
    // Update your UI objects here
}

Mungkin terlihat seperti lebih banyak kode, tetapi tanggung jawab ada di tempat yang tepat sekarang


3
2017-09-06 11:59



Sebenarnya pada iOS 4 saya lebih suka menggunakan NSNotifications dan Pengamat (dengan Blok) untuk melakukan pembaruan pada utarakan utama.

- (id)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *))block

Saya menuliskan desain saya sini.


2
2017-12-21 12:55



1) Deklarasikan protokol delegasi Anda untuk memperluas protokol NSObject dalam file .h

@protocol YourDelegateProtocol <NSObject>

2) Transmisikan ke NSObject di panggilan Anda

[(NSObject*)delegate performSelectorOnMainThread:@selector(getDealersIDSuccess:) withObject:result waitUntilDone:YES];

Saya merekomendasikan nomor (1).


2
2017-12-21 12:58