NSOperationQueue ....发送无法识别的选择器

时间:2016-02-05 10:56:35

标签: ios objective-c contact addressbook nsoperationqueue

我正在尝试实施联系人应用。

在MyContactsViewController中,我试图访问Contacts,如果授予访问权限,我将从我的地址簿中获取联系人。 getAllContacts是我的模型类(单例),它有一个名为- (void)viewDidLoad { [super viewDidLoad]; contactHandler = [ContactHandler sharedInstance]; if(!self.accessGranted){ NSOperationQueue *queue =[[ NSOperationQueue alloc]init]; [queue performSelectorOnMainThread:@selector(getAccessToAddressBook) withObject:self waitUntilDone:YES]; contactList = [contactHandler getAllContacts]; } else{ contactList = [contactHandler getAllContacts]; } } -(BOOL)getAccessToAddressBook{ CNContactStore * contactStore = [[CNContactStore alloc] init]; if( [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts] == CNAuthorizationStatusNotDetermined){ [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) { if(granted){ self.accessGranted = YES; } else{ self.accessGranted = NO; } }]; } else if( [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts]== CNAuthorizationStatusAuthorized){ self.accessGranted = YES; } else{ self.accessGranted = NO; } return self.accessGranted; } 的方法来获取NSMutableArray中的联系人。

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSOperationQueue getAccessToAddressBook]: unrecognized selector sent to instance 0x137630700'

但是我收到了这个错误 -

.gridster {
    background: #004756;
       margin: 0 auto;
    opacity: .8;
    -webkit-transition: opacity .6s;
    -moz-transition: opacity .6s;
    -o-transition: opacity .6s;
    -ms-transition: opacity .6s;
    transition: opacity .6s;
    text-align: center;
}
.gridster > * {
    margin: 0 auto;
    -webkit-transition: height .4s;
    -moz-transition: height .4s;
    -o-transition: height .4s;
    -ms-transition: height .4s;
    transition: height .4s;
}

.gridster .gs_w{
    z-index: 2;
    position: absolute;
        background: #FFF;
    cursor: pointer;
    -webkit-box-shadow: 0 0 5px rgba(0,0,0,0.3);
    box-shadow: 0 0 5px rgba(0,0,0,0.3);
}

.ready .gs_w:not(.preview-holder) {
    -webkit-transition: opacity .3s, left .3s, top .3s;
    -moz-transition: opacity .3s, left .3s, top .3s;
    -o-transition: opacity .3s, left .3s, top .3s;
    transition: opacity .3s, left .3s, top .3s;
}

.ready .gs_w:not(.preview-holder) {
    -webkit-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s;
    -moz-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s;
    -o-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s;
    transition: opacity .3s, left .3s, top .3s, width .3s, height .3s;
}

.gridster .preview-holder {
    z-index: 1;
    position: absolute;
    background-color: #fff;
    border-color: #fff;
    opacity: 0.3;
}

.gridster .player-revert {
    z-index: 10!important;
    -webkit-transition: left .3s, top .3s!important;
    -moz-transition: left .3s, top .3s!important;
    -o-transition: left .3s, top .3s!important;
    transition:  left .3s, top .3s!important;
}

.gridster .dragging {
    z-index: 10!important;
    -webkit-transition: all 0s !important;
    -moz-transition: all 0s !important;
    -o-transition: all 0s !important;
    transition: all 0s !important;
}

.gridWrapper {
   width: 100%;

    overflow-x: scroll;
    overflow-y: hidden;
}

.gridAlignerWrapper {
    display: table;
    width: 100%;
    height: 100%;
}

.gridAligner {
    width: 100%;
    display: table-cell;
        }

body {
    background-color: #EEEEEE;
    font-family: 'Helvetica Neue', Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    font-size: x-small;
    color: #666666;
    text-align: center;
      vertical-align: middle;
}

ul, ol {
    list-style: none;
    margin:0 auto;
      text-align: center;
      vertical-align: middle;


}

h1 {
  margin-bottom: 12px;
  text-align: center;
  font-size: 30px;
  font-weight: 400; 
}

h3 {
  font-size: 25px;
  font-weight: 600;
  color: white; 
}

/* Uncomment this if you set helper : "clone" in draggable options */
/*.gridster .player {
  opacity:0;
}*/

任何人都可以帮忙。

2 个答案:

答案 0 :(得分:1)

你的问题就在这一行:

[queue performSelectorOnMainThread:@selector(getAccessToAddressBook) withObject:self waitUntilDone:YES];

queue拥有此选择器的人getAccessToAddressBook时,您要求self执行getAccessToAddressBook

如果要在队列中运行方法package com.example.trynot; import java.io.IOException; import java.util.Calendar; import java.util.Locale; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import javax.mail.Address; import javax.mail.BodyPart; import javax.mail.Flags; import javax.mail.Folder; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.NoSuchProviderException; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Store; import javax.mail.Flags.Flag; import javax.mail.search.FlagTerm; import com.example.trynot.MainActivity; import com.example.trynot.R; import android.annotation.SuppressLint; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningServiceInfo; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.sax.StartElementListener; import android.speech.tts.TextToSpeech; import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat.Builder; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; import android.speech.tts.TextToSpeech; public class MainActivity extends Activity { public static Context c,b; public static Intent serviceIntent; private static int myNotificationId; public static class ReadMailSample extends AsyncTask<String,String,Void> implements TextToSpeech.OnInitListener{ Message message; private TextToSpeech tts; static String command, phoneNumber, type, priority, name, time_stamp, imei, opt1, opt2, opt3, fromSubString; Properties properties = null; private Session session = null; private Store store = null; private Folder inbox = null; String userName="avarote1994@gmail.com" ; // PROVIDE RECEPIENT EMAIL ID String password="amul11111994" ; // PROVIDE RECEPIENT PASSWORD static SQLiteDatabase db; boolean flag=false; Context acn; //private Bundle savedInstanceState; protected Void doInBackground(String...params){ // SEPARATE THREAD TO RUN IN THE BACKGROUND try{ readMails(); } catch(Exception e){ Logger logger = Logger.getAnonymousLogger(); logger.log(Level.INFO, "an exception was thrown", e); } return null; } ReadMailSample(SQLiteDatabase db){ this.db = db; } ReadMailSample(){ } ReadMailSample(Context cn){ acn=cn; } @Override protected void onProgressUpdate(String... values) { try { System.out.println("---------------------adasd-----------" + time_stamp); speakOut(); showNotification(); } catch(Exception e){ e.printStackTrace(); } } public void onDestroy() { // Don't forget to shutdown tts! if (tts != null) { tts.stop(); tts.shutdown(); } //super.onDestroy(); } @Override public void onInit(int status) { if (status == TextToSpeech.SUCCESS) { int result = tts.setLanguage(Locale.US); if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { Log.e("TTS", "This Language is not supported"); } else { speakOut(); } } else { Log.e("TTS", "Initilization Failed!"); } } private void speakOut() { tts.speak(command, TextToSpeech.QUEUE_FLUSH, null); } public void showNotification() { PendingIntent notificationIntent = preparePendingIntent(); Notification notification = createBasicNotification(notificationIntent); displayNotification(notification); } @SuppressLint("InlinedApi") private PendingIntent preparePendingIntent() { Intent intent=new Intent(c,MainActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivity( c, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); return pendingIntent; } private Notification createBasicNotification(PendingIntent notificationIntent) { NotificationCompat.Builder builder = new Builder(c); long[] vibrationPattern = {0, 200, 800, 200, 600, 200, 400, 200, 200, 200, 100, 200, 50, 200, 50, 200, 50, 200, 50, 200}; Notification notification = builder .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Medication Reminder") .setContentText(command) .setAutoCancel(true) .setContentIntent(notificationIntent) .setWhen(Calendar.getInstance().getTimeInMillis() + 1000*60+60) .setVibrate(vibrationPattern) .build(); return notification; } private void displayNotification(Notification notification) { NotificationManager notificationManager = (NotificationManager)c.getSystemService(Context.NOTIFICATION_SERVICE); myNotificationId=(int) System.currentTimeMillis(); notificationManager.notify(myNotificationId , notification); speakOut(); } public void readMails() throws IOException{ System.out.println("READMAIL hi"); properties = new Properties(); // SETTING UP AN IMAP SERVER TO ACCESS THE RECEPIENT'S EMAIL properties.setProperty("mail.host", "imap.gmail.com"); properties.setProperty("mail.port", "995"); properties.setProperty("mail.transport.protocol", "imaps"); while(true){// CONTINUOUSLY MONITOR INCOMING MAIL'S //String cq = "select * from Login4"; //Cursor c = db.rawQuery(cq, null); // c.moveToFirst(); //final String userName = c.getString(0); //final String password = c.getString(1); //String cloud = "avarote1994@gmail.com"; // AUTHENTICATE AND GET AN INSTANCE OF THE SESSION FROM THE SERVER session = Session.getInstance(properties,new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(userName, password); } }); try { store = session.getStore("imaps"); store.connect(); inbox = store.getFolder("INBOX"); // ACCESS THE INBOX OF THE RECEPIENT'S EMAIL ID inbox.open(Folder.READ_WRITE); // OPEN THE INBOX IN READ-WRITE MODE Message messages[] = inbox.search(new FlagTerm(new Flags(Flag.SEEN), false)); //SEARCH INBOX FOR ANY UNREAD MAILS System.out.println("Number of mails = " + messages.length); for (int i = 0; i < messages.length; i++) { // PROCESS ALL THE UNREAD MAILS message = messages[i]; Address[] from = message.getFrom(); String from1 = from[0].toString(); System.out.println(from1); if(from1.contains("<")){ int start = from1.indexOf("<"); int end = from1.indexOf(">"); fromSubString = from1.substring(start+1,end); // RETRIEVE THE SENDER'S EMAIL ID } else{ fromSubString = from1; } System.out.println(fromSubString); //if(fromSubString.equals(cloud)){ // CHECK WHETHER THE MAIL IS FROM THE CLOUD String[] subject = message.getSubject().split(","); // SPLIT THE SUBJECT System.out.println("hi"); type = subject[0]; // STORE THE DETAILS IN RESPECTIVE VARIABLES phoneNumber =subject[1]; name = subject[2]; System.out.println(type); System.out.println(phoneNumber); System.out.println(name); //String body=message.getContentType().toString(); // System.out.print(body); processMessageBody(message); System.out.println("--------------------------------"); // } } inbox.close(true); store.close(); } catch (NoSuchProviderException e) { e.printStackTrace(); } catch (MessagingException e) { e.printStackTrace(); } } } public void processMessageBody(Message message) { try { Object content = message.getContent(); String msg=content.toString(); System.out.println(msg); if (content instanceof Multipart) { // IF MAIL HAS MULTIPART MESSAGE Multipart multiPart = (Multipart) content; procesMultiPart(multiPart); } else{ System.out.println("Content = "+content); processSinglepart(content.toString()); } } catch (IOException e) { e.printStackTrace(); } catch (MessagingException e) { e.printStackTrace(); } } public void processSinglepart(String content){ String[] body = content.split(","); // SPLIT THE CONTENTS OF THE BODY System.out.println('1'); time_stamp = body[0]; // STORE THE DETAILS IN RESPECTIVE VARIABLES command = body[3]; System.out.println(time_stamp); //tts.speak(time_stamp, TextToSpeech.QUEUE_FLUSH, null); publishProgress(command); } public void procesMultiPart(Multipart content) { System.out.println("amulya"); try { BodyPart bodyPart = content.getBodyPart(0); // RETRIEVE THE CONTENTS FROM THE BODY Object o; o = bodyPart.getContent(); if (o instanceof String) { System.out.println("Content Multipart= "+o.toString()); processSinglepart(o.toString()); } } catch (IOException e) { e.printStackTrace(); } catch (MessagingException e) { e.printStackTrace(); } } } @Override protected void onCreate(Bundle savedInstanceState) { c = this.getApplicationContext(); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (!isMyServiceRunning()){ serviceIntent = new Intent(getApplicationContext(),MyService.class); c.startService(serviceIntent); } final SQLiteDatabase db = openOrCreateDatabase("GDV_DB_NEW_0711", Context.MODE_PRIVATE, null); db.execSQL("CREATE TABLE IF NOT EXISTS Login4(mailid VARCHAR,password VARCHAR);"); db.execSQL("CREATE TABLE IF NOT EXISTS CLIENT_DATA(type VARCHAR,time_stamp VARCHAR,priority VARCHAR,result VARCHAR,opt1 VARCHAR,opt2 VARCHAR,opt3 VARCHAR);"); ReadMailSample rd=new ReadMailSample(getApplicationContext()); System.out.println("hello"); rd.execute(); System.out.println("------xvsdfsdfsd---------aefaefa-----------------"); } private boolean isMyServiceRunning() { ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { if (MyService.class.getName().equals(service.service.getClassName())) { return true; } } return false; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } ,可以使用- addOperationWithBlock:

答案 1 :(得分:0)

就像在这一行:performSelectorOnMainThread你正在传递withObject:self,在方法定义中,即(BOOL)getAccessToAddressBook你没有使用它,这导致了崩溃,所以make {{1如果你不想将任何对象或值传递给方法。

更改此行: -

withObject:nil

到此: -

 [queue performSelectorOnMainThread:@selector(getAccessToAddressBook) withObject:self waitUntilDone:YES];

或者更好的方法是这样写: -

 [queue performSelectorOnMainThread:@selector(getAccessToAddressBook) withObject:nil waitUntilDone:YES];