www.91084.com

GVKun编程网logo

objective-c – 在Sublime Text 2中获取Cocoa方法完成(获取object的key)

22

想了解objective-c–在SublimeText2中获取Cocoa方法完成的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于获取object的key的相关问题,此外,我们还将为您介绍关于

想了解objective-c – 在Sublime Text 2中获取Cocoa方法完成的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于获取object的key的相关问题,此外,我们还将为您介绍关于cocoa – 使用NSManagedObjectContext的objectWithID的“正确”方法是什么:、io.reactivex.subjects.CompletableSubject的实例源码、io.reactivex.subjects.PublishSubject的实例源码、Objective-C 2.0 with Cocoa Foundation--- 6,NSObject的奥秘的新知识。

本文目录一览:

objective-c – 在Sublime Text 2中获取Cocoa方法完成(获取object的key)

objective-c – 在Sublime Text 2中获取Cocoa方法完成(获取object的key)

过去几天我一直在玩Sublime Text 2,并且想知道是否有人在 Cocoa方法完成工作中取得了成功吗?那里有插件(或正在创建的插件项目)吗?

关于在Chocolat或Sublime Text 2中使用Objective-C的任何一般性评论也将受到欢迎.

解决方法

有一个正在进行的Sublime Text包连接到clang以获取名为 SublimeClang的自动完成数据我没有成功地使它完全与Cocoa / UIKit Dev一起工作,但是这里有一个截图

和我的options,这是一个开始

cocoa – 使用NSManagedObjectContext的objectWithID的“正确”方法是什么:

cocoa – 使用NSManagedObjectContext的objectWithID的“正确”方法是什么:

文档说明:

…This method always returns an object.
The data in the persistent store
represented by objectID is assumed to
exist—if it does not,the returned
object throws an exception when you
access any property (that is,when the
fault is fired). The benefit of this
behavior is that it allows you to
create and use faults,then create the
underlying rows later or in a separate
context.

在Apple的’Core Recipes’示例应用程序中,该方法的结果用于填充NSFetchRequest,然后使用请求的结果,并对此结果进行注释:

// first get the object into the context
 Recipe *recipeFault = (Recipe *)[context objectWithID:objectID];

 // this only creates a fault,which may NOT resolve to an object (for example,if the ID is for
 // an objec that has been deleted already):  create a fetch request to get the object for real
 NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
 [request setEntity: [NSEntityDescription entityForName:@"Recipe" inManagedobjectContext:context]];
 nspredicate *predicate = [nspredicate predicateWithFormat: @"(self == %@)",recipeFault];
                    [request setPredicate: predicate];

我看过很多例子(其他代码和apple的’iClass’),其中objectWithID的结果直接使用 – 意思是,它的属性被访问并快速处理.

objectWithID是否应始终被视为“可能存在”的对象?

我问,因为我刚刚遇到这个并没有反对它的存在.

解决方法

Apple文档告诉您的不是假设对象存在是持久性存储,只是因为返回了一个对象.

您可以像对待它一样对待它,访问其属性等等,因为在后台Core Data将访问数据存储来为您的请求提供服务.但是,如果商店中不存在该对象,您将获得异常.

Here’s Apple’s documentation explaining faults(这是objectWithID:返回给你).

io.reactivex.subjects.CompletableSubject的实例源码

io.reactivex.subjects.CompletableSubject的实例源码

项目:async-sqs    文件:KeyedTaskBufferTest.java   
@Test
public void shouldContinueRunningAfterExceptionInTask(){
    AtomicBoolean firstRun = new AtomicBoolean(true);
    CompletableSubject completedSecondRun = CompletableSubject.create();
    KeyedTaskBuffer<String,Integer> taskBuffer = new KeyedTaskBuffer<>(BUFFER_SIZE_2,MAX_WAIT_MILLIS_100,(key,batch) -> {
                if(firstRun.getAndSet(false)){
                    throw new RuntimeException("Test exception");
                }else{
                    completedSecondRun.onComplete();
                }
            });
    taskBuffer.addData(KEY_A,1);
    taskBuffer.addData(KEY_B,1);

    //unit test can only finish if this is completed
    completedSecondRun.timeout(1000,TimeUnit.MILLISECONDS).blockingAwait();
}
项目:disposableAttach    文件:disposableAttachCompletableTest.java   
@Test public void test() {


        CompletableSubject subject = CompletableSubject.create();
        Completable source = subject.hide();


        TestObserver testObserver = new TestObserver();
        Compositedisposable composite = new Compositedisposable();
        disposable disposable = source
                .compose(disposableAttach.<String>to(composite))
                .subscribeWith(testObserver);

        assertTrue(composite.size() == 1);
        composite.dispose();
        assertTrue(composite.size() == 0);
        assertTrue(composite.isdisposed());
        assertTrue(disposable.isdisposed());
        assertTrue(testObserver.isdisposed());
    }
项目:delern    文件:MultiWrite.java   
/**
 * Apply all the queued operations to the database.
 *
 * @return Observable,either immediately available (when offline) or triggered on
 * Firebase success/failure event.
 */
public Completable write() {
    CompletableSubject subject = CompletableSubject.create();

    LOGGER.info("Writing with online={},operations in queue: {}",ServerConnection.isOnline(),OPERATIONS_IN_FLIGHT);
    OPERATIONS_IN_FLIGHT.incrementAndGet();

    Throwable writerStackTrace = new Throwable();

    mRoot.updateChildren(mData)
            .addOnSuccessListener((final Void p) -> subject.onComplete())
            .addOnFailureListener((final Exception e) -> {
                e.setStackTrace(writerStackTrace.getStackTrace());
                LOGGER.error("Failed to save {}",mData,e);
                subject.onError(e);
            })
            .addOnCompleteListener(t -> OPERATIONS_IN_FLIGHT.decrementAndGet());

    if (ServerConnection.isOnline()) {
        return subject;
    } else {
        return Completable.complete();
    }
}
项目:Autodispose    文件:AutodisposeCompletableObserverTest.java   
@Test public void autodispose_withMaybe_normal() {
  RecordingObserver<Integer> o = new RecordingObserver<>(LOGGER);
  CompletableSubject source = CompletableSubject.create();
  MaybeSubject<Integer> lifecycle = MaybeSubject.create();
  source.as(autodisposable(lifecycle))
      .subscribe(o);
  o.takeSubscribe();

  assertthat(source.hasObservers()).isTrue();
  assertthat(lifecycle.hasObservers()).isTrue();

  // Got the event
  source.onComplete();
  o.assertOnComplete();

  // nothing more,lifecycle disposed too
  o.assertNoMoreEvents();
  assertthat(source.hasObservers()).isFalse();
  assertthat(lifecycle.hasObservers()).isFalse();
}
项目:Autodispose    文件:AutodisposeCompletableObserverTest.java   
@Test public void autodispose_withMaybe_interrupted() {
  RecordingObserver<Integer> o = new RecordingObserver<>(LOGGER);
  CompletableSubject source = CompletableSubject.create();
  MaybeSubject<Integer> lifecycle = MaybeSubject.create();
  source.as(autodisposable(lifecycle))
      .subscribe(o);
  o.takeSubscribe();

  assertthat(source.hasObservers()).isTrue();
  assertthat(lifecycle.hasObservers()).isTrue();

  // Lifecycle ends
  lifecycle.onSuccess(2);
  assertthat(source.hasObservers()).isFalse();
  assertthat(lifecycle.hasObservers()).isFalse();

  // Event if upstream emits,no one is listening
  source.onComplete();
  o.assertNoMoreEvents();
}
项目:Autodispose    文件:AutodisposeCompletableObserverTest.java   
@Test public void autodispose_withProvider_completion() {
  RecordingObserver<Integer> o = new RecordingObserver<>(LOGGER);
  CompletableSubject source = CompletableSubject.create();
  MaybeSubject<Integer> scope = MaybeSubject.create();
  ScopeProvider provider = makeProvider(scope);
  source.as(autodisposable(provider))
      .subscribe(o);
  o.takeSubscribe();

  assertthat(source.hasObservers()).isTrue();
  assertthat(scope.hasObservers()).isTrue();

  source.onComplete();
  o.assertOnComplete();

  o.assertNoMoreEvents();
  assertthat(source.hasObservers()).isFalse();
  assertthat(scope.hasObservers()).isFalse();
}
项目:Autodispose    文件:AutodisposeCompletableObserverTest.java   
@Test public void autodispose_withProvider_interrupted() {
  RecordingObserver<Integer> o = new RecordingObserver<>(LOGGER);
  CompletableSubject source = CompletableSubject.create();
  MaybeSubject<Integer> scope = MaybeSubject.create();
  ScopeProvider provider = makeProvider(scope);
  source.as(autodisposable(provider))
      .subscribe(o);
  o.takeSubscribe();

  assertthat(source.hasObservers()).isTrue();
  assertthat(scope.hasObservers()).isTrue();

  scope.onSuccess(1);

  // All disposed
  assertthat(source.hasObservers()).isFalse();
  assertthat(scope.hasObservers()).isFalse();

  // No one is listening
  source.onComplete();
  o.assertNoMoreEvents();
}
项目:Autodispose    文件:AutodisposeCompletableObserverTest.java   
@Test public void autodispose_withLifecycleProvider_completion() {
  RecordingObserver<Integer> o = new RecordingObserver<>(LOGGER);
  CompletableSubject source = CompletableSubject.create();
  BehaviorSubject<Integer> lifecycle = BehaviorSubject.createDefault(0);
  LifecycleScopeProvider<Integer> provider = makeLifecycleProvider(lifecycle);
  source.as(autodisposable(provider))
      .subscribe(o);
  o.takeSubscribe();

  assertthat(source.hasObservers()).isTrue();
  assertthat(lifecycle.hasObservers()).isTrue();

  lifecycle.onNext(1);

  assertthat(source.hasObservers()).isTrue();
  assertthat(lifecycle.hasObservers()).isTrue();

  source.onComplete();
  o.assertOnComplete();

  o.assertNoMoreEvents();
  assertthat(source.hasObservers()).isFalse();
  assertthat(lifecycle.hasObservers()).isFalse();
}
项目:Autodispose    文件:AutodisposeCompletableObserverTest.java   
@Test public void autodispose_withProviderAndNoOpPlugin_withoutStarting_shouldFailSilently() {
  AutodisposePlugins.setoutsideLifecycleHandler(new Consumer<OutsideLifecycleException>() {
    @Override public void accept(OutsideLifecycleException e) { }
  });
  BehaviorSubject<Integer> lifecycle = BehaviorSubject.create();
  LifecycleScopeProvider<Integer> provider = TestUtil.makeLifecycleProvider(lifecycle);
  CompletableSubject source = CompletableSubject.create();
  TestObserver<Void> o = source
          .as(autodisposable(provider))
          .test();

  assertthat(source.hasObservers()).isFalse();
  assertthat(lifecycle.hasObservers()).isFalse();
  o.assertNovalues();
  o.assertNoErrors();
}
项目:Autodispose    文件:AutodisposeCompletableObserverTest.java   
@Test public void autodispose_withProviderAndNoOpPlugin_afterEnding_shouldFailSilently() {
  AutodisposePlugins.setoutsideLifecycleHandler(new Consumer<OutsideLifecycleException>() {
    @Override public void accept(OutsideLifecycleException e) {
      // Noop
    }
  });
  BehaviorSubject<Integer> lifecycle = BehaviorSubject.createDefault(0);
  lifecycle.onNext(1);
  lifecycle.onNext(2);
  lifecycle.onNext(3);
  LifecycleScopeProvider<Integer> provider = TestUtil.makeLifecycleProvider(lifecycle);
  CompletableSubject source = CompletableSubject.create();
  TestObserver<Void> o = source
          .as(autodisposable(provider))
          .test();

  assertthat(source.hasObservers()).isFalse();
  assertthat(lifecycle.hasObservers()).isFalse();
  o.assertNovalues();
  o.assertNoErrors();
}
项目:Autodispose    文件:AutodisposeCompletableObserverTest.java   
@Test public void autodispose_withProviderAndplugin_withoutStarting_shouldFailWithWrappedExp() {
  AutodisposePlugins.setoutsideLifecycleHandler(new Consumer<OutsideLifecycleException>() {
    @Override public void accept(OutsideLifecycleException e) {
      // Wrap in an IllegalStateException so we can verify this is the exception we see on the
      // other side
      throw new IllegalStateException(e);
    }
  });
  BehaviorSubject<Integer> lifecycle = BehaviorSubject.create();
  LifecycleScopeProvider<Integer> provider = TestUtil.makeLifecycleProvider(lifecycle);
  TestObserver<Void> o = CompletableSubject.create()
            .as(autodisposable(provider))
            .test();

  o.assertNovalues();
  o.assertError(new Predicate<Throwable>() {
    @Override public boolean test(Throwable throwable) {
      return throwable instanceof IllegalStateException
          && throwable.getCause() instanceof OutsideLifecycleException;
    }
  });
}
项目:async-sqs    文件:MessageAckNowledger.java   
public MessageAckNowledger(SqsQueue<T> sqsQueue,String receiptId,Instant expirationTime) {
    this.expirationTime = expirationTime;
    this.sqsQueue = sqsQueue;
    this.receiptId = receiptId;
    this.ackModeSingle = SingleSubject.create();
    this.ackingComplete = CompletableSubject.create();

    Duration duration = Duration.between(Instant.Now(),expirationTime);
    Completable.timer(duration.toMillis(),TimeUnit.MILLISECONDS).subscribe(this::ignore);
}
项目:RxJava2Jdk8Interop    文件:CompletableInterop.java   
/**
 * Returns a Completable that terminates when the given CompletionStage terminates.
 * @param future the source CompletionStage instance
 * @return the new Completable instance
 */
public static Completable fromFuture(CompletionStage<?> future) {
    CompletableSubject cs = CompletableSubject.create();

    future.whenComplete((v,e) -> {
        if (e != null) {
            cs.onError(e);
        } else {
            cs.onComplete();
        }
    });

    return cs;
}
项目:Autodispose    文件:AutodisposeCompletableObserverTest.java   
@Test public void autodispose_withLifecycleProvider_interrupted() {
  RecordingObserver<Integer> o = new RecordingObserver<>(LOGGER);
  CompletableSubject source = CompletableSubject.create();
  BehaviorSubject<Integer> lifecycle = BehaviorSubject.createDefault(0);
  LifecycleScopeProvider<Integer> provider = makeLifecycleProvider(lifecycle);
  source.as(autodisposable(provider))
      .subscribe(o);
  o.takeSubscribe();

  assertthat(source.hasObservers()).isTrue();
  assertthat(lifecycle.hasObservers()).isTrue();

  lifecycle.onNext(1);

  assertthat(source.hasObservers()).isTrue();
  assertthat(lifecycle.hasObservers()).isTrue();

  lifecycle.onNext(3);

  // All disposed
  assertthat(source.hasObservers()).isFalse();
  assertthat(lifecycle.hasObservers()).isFalse();

  // No one is listening
  source.onComplete();
  o.assertNoMoreEvents();
}
项目:Autodispose    文件:AutodisposeCompletableObserverTest.java   
@Test public void autodispose_withScopeProviderCompleted_shouldNotReportDoubleSubscriptions() {
  TestObserver<Void> o = CompletableSubject.create()
            .as(autodisposable(ScopeProvider.UNBOUND))
            .test();
  o.assertNovalues();
  o.assertNoErrors();

  rule.assertNoErrors();
}
项目:Autodispose    文件:AutodisposeCompletableObserverTest.java   
@Test public void unbound_shouldStillPassValues() {
  TestObserver<Void> o = CompletableSubject.create()
          .as(autodisposable(ScopeProvider.UNBOUND))
          .test();

  o.onComplete();
  o.assertComplete();
}
项目:async-sqs    文件:DeleteMessageEntry.java   
@Default
public CompletableSubject getResultSubject() {
    return CompletableSubject.create();
}
项目:async-sqs    文件:ChangeMessageVisibilityEntry.java   
@Default
public CompletableSubject getResultSubject() {
    return CompletableSubject.create();
}
项目:async-sqs    文件:retryingSqsQueue.java   
@Override
public Completable deleteMessage(String receiptHandle) {
    return Completable.defer(() -> delegate.deleteMessage(receiptHandle))
            .retry(this::shouldRetry)
            .subscribeWith(CompletableSubject.create());//convert to Hot completable
}
项目:async-sqs    文件:retryingSqsQueue.java   
@Override
public Completable changeMessageVisibility(String receiptHandle,Duration newVisibility) {
    return Completable.defer(() -> delegate.changeMessageVisibility(receiptHandle,newVisibility))
            .retry(this::shouldRetry)
            .subscribeWith(CompletableSubject.create());//convert to Hot completable
}

io.reactivex.subjects.PublishSubject的实例源码

io.reactivex.subjects.PublishSubject的实例源码

项目:https-github.com-hyb1996-norootScriptDroid    文件:ScriptOperations.java   
private Observable<String> showNameInputDialog(String prefix,MaterialDialog.InputCallback textWatcher) {
    final PublishSubject<String> input = PublishSubject.create();
    DialogUtils.showDialog(new ThemeColorMaterialDialogBuilder(mContext).title(R.string.text_name)
            .inputType(InputType.TYPE_CLASS_TEXT)
            .alwaysCallInputCallback()
            .input(getString(R.string.text_please_input_name),prefix,false,textWatcher)
            .onPositive(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog,@NonNull DialogAction which) {
                    input.onNext(dialog.getInputEditText().getText().toString());
                    input.onComplete();
                }
            })
            .build());
    return input;
}
项目:RxJava2-Android-Sample    文件:PublishSubjectExampleActivity.java   
/**
 * PublishSubject只会把在订阅发生的时间点之后来自原始Observable的数据发射给观察者。
 * 需要注意的是,PublishSubject可能会一创建完成就立刻开始发射数据(除非你可以阻止它发生),
 * 因此这里有一个风险:在Subject被创建后到有观察者订阅它之前这个时间段内,一个或多个数据可能会丢失。
 * 如果要确保来自原始Observable的所有数据都被分发:
 * 1.使用Create创建那个Observable以便手动给它引入"冷"Observable的行为(当所有观察者都已经订阅时才开始发射数据)
 * 2.改用ReplaySubject。
 *
 * 如果原始的Observable因为发生了一个错误而终止,PublishSubject将不会发射任何数据,只是简单的向前传递这个错误通知。
 */
private void doSomeWork() {

    PublishSubject<Integer> source = PublishSubject.create();

    source.subscribe(getFirstObserver()); // it will get 1,2,3,4 and onComplete

    source.onNext(1);
    source.onNext(2);
    source.onNext(3);

    /*
     * it will emit 4 and onComplete for second observer also.
     */
    source.subscribe(getSecondobserver());

    source.onNext(4);
    source.onComplete();
}
项目:AesExoPlayer    文件:RxPermissionsFragment.java   
void onRequestPermissionsResult(String permissions[],int[] grantResults,boolean[] shouldShowRequestPermissionRationale) {
    for (int i = 0,size = permissions.length; i < size; i++) {
        Log.i("","onRequestPermissionsResult  " + permissions[i]);
        // Find the corresponding subject
        PublishSubject<Permission> subject = mSubjects.get(permissions[i]);
        if (subject == null) {
            // No subject found
            Log.e(RxPermissions.TAG,"RxPermissions.onRequestPermissionsResult invoked but didn't find the corresponding permission request.");
            return;
        }
        mSubjects.remove(permissions[i]);
        boolean granted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
        subject.onNext(new Permission(permissions[i],granted,shouldShowRequestPermissionRationale[i]));
        subject.onComplete();
    }
}
项目:java-debug    文件:ProcessConsole.java   
private void monitor(InputStream input,PublishSubject<String> subject) {
    BufferedReader reader = new BufferedReader(new InputStreamReader(input,encoding));
    final int BUFFERSIZE = 4096;
    char[] buffer = new char[BUFFERSIZE];
    while (true) {
        try {
            if (Thread.interrupted()) {
                subject.onComplete();
                return;
            }
            int read = reader.read(buffer,BUFFERSIZE);
            if (read == -1) {
                subject.onComplete();
                return;
            }

            subject.onNext(new String(buffer,read));
        } catch (IOException e) {
            subject.onError(e);
            return;
        }
    }
}
项目:grpc-mate    文件:ProductReadService.java   
@Override
public void downloadProducts(DownloadProductsRequest request,StreamObserver<Product> responSEObserver) {
  PublishSubject<Product> productPublishSubject = PublishSubject.create();
  productPublishSubject
      .doOnNext(product -> {
        responSEObserver.onNext(product);
        counter.labels("downloadProducts","success");
      })
      .doOnComplete(() -> responSEObserver.onCompleted())
      .doOnError(t -> {
        responSEObserver.onError(t);
        counter.labels("downloadProducts","Failed");
      })
      .subscribe();
  productDao.downloadProducts(request,productPublishSubject);
}
项目:EditPhoto    文件:BrightnessView.java   
private void initView() {
        subject = PublishSubject.create();
        subject.debounce(0,TimeUnit.MILLISECONDS)
//                .filter(new Predicate<Float>() {
//                    @Override
//                    public boolean test(Float brightness) throws Exception {
//                        return true;
//                    }
//                })
                .distinctUntilChanged()
                .switchMap(new Function<Float,ObservableSource<ColorMatrixColorFilter>>() {
                    @Override
                    public ObservableSource<ColorMatrixColorFilter> apply(Float value) throws Exception {
                        return postBrightness(value);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<ColorMatrixColorFilter>() {
                    @Override
                    public void accept(ColorMatrixColorFilter colorMatrixColorFilter) throws Exception {
                        setColorFilter(colorMatrixColorFilter);
                    }
                });
    }
项目:clustercode    文件:TranscodingServiceImpl.java   
@Inject
TranscodingServiceImpl(ExternalProcessService externalProcessService,TranscoderSettings transcoderSettings,MediaScanSettings mediaScanSettings,OutputParser parser) {
    this.externalProcessService = externalProcessService;
    this.transcoderSettings = transcoderSettings;
    this.mediaScanSettings = mediaScanSettings;

    this.parser = parser;

    this.publisher = PublishSubject.create().toSerialized();

    publisher.ofType(TranscodeTask.class)
             .skipwhile(o -> isActive())
             .observeOn(Schedulers.computation())
             .subscribeOn(Schedulers.io())
             .subscribe(this::prepareTranscode);
}
项目:KTools    文件:TwoWayDataBidingFragment.java   
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_two_way_data_biding,container,false);
    unbinder = ButterKnife.bind(this,view);

    publishSubject = PublishSubject.create();

    publishSubject.subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            mTvAddResult.setText(s);
        }
    });

    onNumChanged();

    MetaddLeft.requestFocus();

    return view;
}
项目:github-users    文件:UserListPresenterTest.java   
@Test
public void onUserQueryEvent_emptyQueryString_shouldDonothingWithView() {
  // given
  PublishSubject<UserQueryEvent> userQuery$ = PublishSubject.create();
  UserListPresenter presenter = new UserListPresenter(
      userQuery$,userService,() -> mock(UserView.class),() -> mock(UserPresenter.class),DEFAULT_PAGE_SIZE,DEFAULT_USER_SEARCH_LIMIT
  );
  presenter.start(view);
  UserQueryEvent event = new UserQueryEvent(" "); // empty string

  // when
  userQuery$.onNext(event);

  // then
  verifyNoMoreInteractions(view,userService);
}
项目:RxPermissions    文件:RxPermissionsFragment.java   
void onRequestPermissionsResult(String permissions[],size = permissions.length; i < size; i++) {
        log("onRequestPermissionsResult  " + permissions[i]);
        // Find the corresponding subject
        PublishSubject<Permission> subject = mSubjects.get(permissions[i]);
        if (subject == null) {
            // No subject found
            Log.e(RxPermissions.TAG,"RxPermissions.onRequestPermissionsResult invoked but didn't find the corresponding permission request.");
            return;
        }
        mSubjects.remove(permissions[i]);
        boolean granted = (grantResults[i] == PackageManager.PERMISSION_GRANTED) && (PermissionChecker.checkSelfPermission(getContext(),permissions[i]) == PermissionChecker.PERMISSION_GRANTED);
        subject.onNext(new Permission(permissions[i],shouldShowRequestPermissionRationale[i]));
        subject.onComplete();
    }
}
项目:RxNetWork    文件:RxBus.java   
/**
 * 接受消息
 *
 * @param tag      标志
 * @param callBack 回调
 */
public <T> disposableObserver registerNoThread(@NonNull final Object tag,@NonNull final RxBusCallBack<T> callBack) {
    RxBusEvent rxBusEvent = rxBusEventArrayMap.get(tag);
    if (RxUtils.isEmpty(rxBusEvent)) {
        rxBusEvent = new RxBusEvent();
        rxBusEvent.subject = PublishSubject.create().toSerialized();
        rxBusEvent.disposable =
                rxBusEvent.subject
                        .ofType(callBack.busOfType())
                        .subscribeWith(new RxBusObserver<T>() {
                            @Override
                            public void onError(@io.reactivex.annotations.NonNull Throwable e) {
                                super.onError(e);
                                callBack.onBusError(e);
                            }

                            @Override
                            public void onNext(@io.reactivex.annotations.NonNull T t) {
                                super.onNext(t);
                            }
                        });
        rxBusEventArrayMap.put(tag,rxBusEvent);
    }
    return rxBusEvent.disposable;
}
项目:github-users    文件:UserPresenterTest.java   
@Test
public void onUserSelected_view_shouldPostUserSelectedEvent() {
  // given
  TestObserver<UserSelectedEvent> userSelected$ = TestObserver.create();
  User user = mock(User.class);
  given(user.getLogin()).willReturn("foo");
  PublishSubject<Trigger> userSelectionIntent = PublishSubject.create();
  given(view.userSelection$()).willReturn(userSelectionIntent);

  UserPresenter presenter = new UserPresenter(Sink.of(userSelected$));
  presenter.start(user,view);

  // when
  fire(userSelectionIntent);

  // then
  userSelected$.assertValueCount(1);
  UserSelectedEvent event = userSelected$.values().get(0);
  assertthat(event.getUser().getLogin()).isEqualTo("foo");
}
项目:Auto.js    文件:UserService.java   
public Observable<Boolean> refreshOnlinestatus() {
    PublishSubject<Boolean> online = PublishSubject.create();
    mRetrofit.create(UserApi.class)
            .me()
            .subscribeOn(Schedulers.io())
            .subscribe(user -> {
                setUser(user);
                online.onNext(true);
                online.onComplete();
            },error -> {
                setUser(null);
                online.onNext(false);
                online.onComplete();
            });
    return online;
}
项目:jobson    文件:JobManagerTest.java   
@Test
public void testGetStderrUpdatesEchoesUpdatesFromExecutorObservers() throws InterruptedException,ExecutionException,TimeoutException {
    final CancelablePromise<JobExecutionResult> executorPromise = new SimpleCancelablePromise<>();
    final Subject<byte[]> stderrSubject = PublishSubject.create();
    final JobExecutor executor =
            MockJobExecutor.thatUses(executorPromise,Observable.just(TestHelpers.generaterandomBytes()),stderrSubject);
    final JobManager jobManager = createManagerWith(executor);

    final Pair<JobId,CancelablePromise<FinalizedJob>> ret =
            jobManager.submit(STANDARD_VALID_REQUEST);

    final Observable<byte[]> stderrObservable =
            jobManager.stderrUpdates(ret.getLeft()).get();

    final atomicreference<byte[]> bytesFromObservable = new atomicreference<>();
    stderrObservable.subscribe(bytesFromObservable::set);

    final byte[] bytesExpected = TestHelpers.generaterandomBytes();
    stderrSubject.onNext(bytesExpected);

    executorPromise.complete(new JobExecutionResult(FINISHED));

    ret.getRight().get(DEFAULT_TIMEOUT,MILLISECONDS);

    assertthat(bytesFromObservable.get()).isEqualTo(bytesExpected);
}
项目:EditPhoto    文件:ContrastView.java   
private void initView() {
        subject = PublishSubject.create();
        subject.debounce(0,TimeUnit.MILLISECONDS)
//                .filter(new Predicate<Float>() {
//                    @Override
//                    public boolean test(Float contrast) throws Exception {
//                        return true;
//                    }
//                })
                .distinctUntilChanged()
                .switchMap(new Function<Float,ObservableSource<ColorMatrixColorFilter>>() {
                    @Override
                    public ObservableSource<ColorMatrixColorFilter> apply(Float value) throws Exception {
                        return postContrast(value);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<ColorMatrixColorFilter>() {
                    @Override
                    public void accept(ColorMatrixColorFilter colorMatrixColorFilter) throws Exception {
                        setColorFilter(colorMatrixColorFilter);
                    }
                });
    }
项目:Auto.js    文件:ScriptOperations.java   
public Observable<ScriptFile> download(String url,String path,MaterialDialog progressDialog) {
    PublishSubject<ScriptFile> subject = PublishSubject.create();
    DownloadManager.getInstance().download(url,path)
            .observeOn(AndroidSchedulers.mainThread())
            .doOnNext(progressDialog::setProgress)
            .subscribe(new SimpleObserver<Integer>() {
                @Override
                public void onComplete() {
                    progressDialog.dismiss();
                    subject.onNext(new ScriptFile(path));
                    subject.onComplete();
                }

                @Override
                public void onError(Throwable error) {
                    Log.e(LOG_TAG,"Download Failed",error);
                    progressDialog.dismiss();
                    showMessage(R.string.text_download_Failed);
                    subject.onError(error);
                }
            });
    return subject;
}
项目:jobson    文件:JobsDAOTest.java   
@Test
public void testPersistStderrReturnsAdisposableThatStopsFurtherReads() {
    final JobDAO dao = getInstance();
    final JobId jobId = dao.persist(STANDARD_VALID_REQUEST).getId();
    final Subject<byte[]> stderrSubject = PublishSubject.create();
    final AtomicBoolean stderrObsWasRead = new AtomicBoolean(false);
    final Observable<byte[]> stderrObs = stderrSubject.map(data -> {
        stderrObsWasRead.set(true);
        return data;
    });

    final disposable disposable = dao.appendStderr(jobId,stderrObs);
    disposable.dispose();
    stderrSubject.onNext(TestHelpers.generaterandomBytes());

    assertthat(stderrObsWasRead.get());
}
项目:jobson    文件:JobExecutorTest.java   
@Test
public void testExecuteStderrListenerIsCompletedOnceApplicationExecutionEnds() throws Throwable {
    final JobExecutor jobExecutor = getInstance();
    final AtomicBoolean completedCalled = new AtomicBoolean(false);
    final Subject<byte[]> stderrSubject = PublishSubject.create();
    stderrSubject.doOnComplete(() -> completedCalled.set(true)).subscribe();
    final JobEventListeners listeners = createStderrListener(stderrSubject);
    final CancelablePromise<JobExecutionResult> ret =
            jobExecutor.execute(STANDARD_REQUEST,listeners);

    promiseAssert(ret,result -> {
        try {
            // The stderr thread can race with the exit thread
            Thread.sleep(50);
            assertthat(completedCalled.get()).isTrue();
        } catch (InterruptedException ignored) {}
    });
}
项目:jobson    文件:JobExecutorTest.java   
@Test
public void testExecuteEvaluatesJobInputsAsExpected() throws InterruptedException {
    final JobExecutor jobExecutor = getInstance();
    final PersistedJob req =
            standardRequestWithCommand("echo","${inputs.foo}");
    final atomicreference<byte[]> bytesEchoedToStdout = new atomicreference<>(new byte[]{});
    final Subject<byte[]> stdoutSubject = PublishSubject.create();

    stdoutSubject.subscribe(bytes ->
            bytesEchoedToStdout.getAndUpdate(existingBytes ->
                    Bytes.concat(existingBytes,bytes)));

    final Semaphore s = new Semaphore(1);
    s.acquire();
    stdoutSubject.doOnComplete(s::release).subscribe();

    final JobEventListeners listeners =
            createStdoutListener(stdoutSubject);

    jobExecutor.execute(req,listeners);

    s.tryAcquire(TestConstants.DEFAULT_TIMEOUT,MILLISECONDS);

    final String stringFromStdout = new String(bytesEchoedToStdout.get()).trim();
    assertthat(stringFromStdout).isEqualTo("a"); // from spec
}
项目:Learning-RxJava    文件:Ch5_22.java   
public static void main(String[] args) {
    Subject<String> subject = PublishSubject.create();
    subject.onNext("Alpha");
    subject.onNext("Beta");
    subject.onNext("Gamma");
    subject.onComplete();
    subject.map(String::length)
            .subscribe(System.out::println);
}
项目:KTools    文件:RxPermissions.java   
@TargetApi(Build.VERSION_CODES.M)
private Observable<Permission> requestImplementation(final String... permissions) {
    List<Observable<Permission>> list = new ArrayList<>(permissions.length);
    List<String> unrequestedPermissions = new ArrayList<>();

    // In case of multiple permissions,we create an Observable for each of them.
    // At the end,the observables are combined to have a unique response.
    for (String permission : permissions) {
        mRxPermissionsFragment.log("Requesting permission " + permission);
        if (isGranted(permission)) {
            // Already granted,or not Android M
            // Return a granted Permission object.
            list.add(Observable.just(new Permission(permission,true,false)));
            continue;
        }

        if (isRevoked(permission)) {
            // Revoked by a policy,return a denied Permission object.
            list.add(Observable.just(new Permission(permission,false)));
            continue;
        }

        PublishSubject<Permission> subject = mRxPermissionsFragment.getSubjectByPermission(permission);
        // Create a new subject if not exists
        if (subject == null) {
            unrequestedPermissions.add(permission);
            subject = PublishSubject.create();
            mRxPermissionsFragment.setSubjectForPermission(permission,subject);
        }

        list.add(subject);
    }

    if (!unrequestedPermissions.isEmpty()) {
        String[] unrequestedPermissionsArray = unrequestedPermissions.toArray(new String[unrequestedPermissions.size()]);
        requestPermissionsFromFragment(unrequestedPermissionsArray);
    }
    return Observable.concat(Observable.fromIterable(list));
}
项目:Learning-RxJava    文件:Ch5_20.java   
public static void main(String[] args) {
    Subject<String> subject = PublishSubject.create();
    subject.map(String::length)
            .subscribe(System.out::println);
    subject.onNext("Alpha");
    subject.onNext("Beta");
    subject.onNext("Gamma");
    subject.onComplete();
}
项目:GitHub    文件:SelectedCountToolbarPresenter.java   
public SelectedCountToolbarPresenter(Observable<Integer> selectedCountObservable,PublishSubject<Boolean> clearSelectionRelay,PublishSubject<Boolean> deleteSelectedItemsRelay) {
  this.selectedCountObservable = selectedCountObservable;
  this.clearSelectionRelay = clearSelectionRelay;
  this.deleteSelectedItemsRelay = deleteSelectedItemsRelay;
}
项目:github-users    文件:DrawerPresenterTest.java   
@Test
public void start_openDrawerIntent_shouldOpenTheDrawer() {
  // given
  TestObserver<SnackbarMessageEvent> snackbarMessage$ = new TestObserver<>();
  PublishSubject<Trigger> openDrawerIntent = PublishSubject.create();
  given(view.openDrawerIntent$()).willReturn(openDrawerIntent);
  given(view.readAboutIntent$()).willReturn(noTriggers());
  given(view.openProjectOnGitHubIntent$()).willReturn(noTriggers());
  given(view.selectLanguageIntent$()).willReturn(noTriggers());
  DrawerPresenter presenter = new DrawerPresenter(
      "http://foo.com",Sink.of(snackbarMessage$),urlOpener
  );
  presenter.start(view);

  // when
  fire(openDrawerIntent);

  // then
  verify(view).openDrawerIntent$();
  verify(view).readAboutIntent$();
  verify(view).openProjectOnGitHubIntent$();
  verify(view).selectLanguageIntent$();
  verify(view).openDrawer(true);
  then(view).shouldHaveNoMoreInteractions();
  then(urlOpener).shouldHaveZeroInteractions();
  snackbarMessage$.assertNovalues();
}
项目:github-users    文件:PresenterTest.java   
@Test
public void onEvent_presenterStopped_shouldIgnoreSubsequentEvent() {
  // given
  PublishSubject<String> subject = PublishSubject.create();
  TestPresenter presenter = new TestPresenter();
  presenter.on(subject).call(subscriber);
  presenter.stop();

  // when
  subject.onNext("foo");

  // then
  verifyZeroInteractions(subscriber);
}
项目:dagger-test-example    文件:SearchviewmodelStubDelegate.java   
@Override
public Searchviewmodel get(NavigationController navigationController,Observable<String> searchObservable,PublishSubject<SearchAdapter> searchAdapterSubject,SearchService searchService,SearchAdapterFactory searchAdapterFactory,Scheduler androidScheduler) {
    return new Searchviewmodel(navigationController,searchObservable,searchAdapterSubject,searchService,searchAdapterFactory,androidScheduler) {
        @Override
        public void search(String city) {
            latch.countDown();
        }
    };
}
项目:XPermission    文件:XPermission.java   
@TargetApi(Build.VERSION_CODES.M)
private Observable<Permission> requestImplementation(Context context,final String... permissions) {
    List<Observable<Permission>> list = new ArrayList<>(permissions.length);
    List<String> unrequestedPermissions = new ArrayList<>();

    // In case of multiple permissions,the observables are combined to have a unique response.
    for (String permission : permissions) {
        XPermissionActivity.log("Requesting permission " + permission);
        if (isGranted(context,permission)) {
            // Already granted,false)));
            continue;
        }

        if (isRevoked(context,permission)) {
            // Revoked by a policy,false)));
            continue;
        }

        PublishSubject<Permission> subject = XPermissionActivity.getSubjectByPermission(permission);
        // Create a new subject if not exists
        if (subject == null) {
            unrequestedPermissions.add(permission);
            subject = PublishSubject.create();
            XPermissionActivity.setSubjectForPermission(permission,subject);
        }

        list.add(subject);
    }

    if (!unrequestedPermissions.isEmpty()) {
        String[] unrequestedPermissionsArray = unrequestedPermissions.toArray(new String[unrequestedPermissions.size()]);
        requestPermissionsFromActivity(context,unrequestedPermissionsArray);
    }
    return Observable.concat(Observable.fromIterable(list));
}
项目:XPermission    文件:XPermissionActivity.java   
void onRequestPermissionsResult(String permissions[],size = permissions.length; i < size; i++) {
        log("onRequestPermissionsResult  " + permissions[i]);
        // Find the corresponding subject
        PublishSubject<Permission> subject = mSubjects.get(permissions[i]);
        if (subject == null) {
            // No subject found
            log("XPermission.onRequestPermissionsResult invoked but didn't find the corresponding permission request.");
            return;
        }
        mSubjects.remove(permissions[i]);
        boolean granted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
        boolean showRequestPermissionRationale = shouldShowRequestPermissionRationale[i];
        log("granted: " + granted + "; showRequestPermissionRationale: " + showRequestPermissionRationale);
        if(Manifest.permission.WRITE_SETTINGS.equals(permissions[i]) || Manifest.permission.SYstem_ALERT_WINDOW.equals(permissions[i])){
            granted = PermissionsChecker.isPermissionGranted(this,permissions[i],false);
        }else{
            if(granted){
                if(PermissionsChecker.isPermissionGranted(this,true)){
                    granted = true;
                }else{
                    granted = false;
                    showRequestPermissionRationale = false;
                }
            }else if(showRequestPermissionRationale){
                if(PermissionsChecker.isPermissionGranted(this,false)){
                    granted = true;
                }else{
                    granted = false;
                }
            }
        }
        subject.onNext(new Permission(permissions[i],showRequestPermissionRationale));
        subject.onComplete();
    }
}
项目:github-users    文件:SnackbarPresenterTest.java   
@Test
public void start_noEventPosted_shouldDonothingWithView() {
  // given
  PublishSubject<SnackbarMessageEvent> snackbarMessage$ = PublishSubject.create();
  SnackbarPresenter presenter = new SnackbarPresenter(snackbarMessage$);

  // when
  presenter.start(view);

  // then
  verifyZeroInteractions(view);
}
项目:redux-observable    文件:Store.java   
Store(@NonNull State initialState,@NonNull Reducer<State> reducer,@NonNull Effect<State>[] effects) {
    this.reducer = reducer;
    this.action$ = PublishSubject.create();
    this.state$ = BehaviorSubject.createDefault(initialState);
    this.result$ = Observable.fromArray(effects)
            .flatMap(transformer -> transformer.apply(action$,this::currentState));
}
项目:Outlast    文件:BaseFragment.java   
/**
 * Subscribes the passed subject to the
 */
protected <T> void bindAction(Observable<T> from,PublishSubject<T> to) {
    composite.add(
            from
                    .doOnNext(t -> Timber.d("bind action called"))
                    .subscribe(to::onNext)
    );
}
项目:AesExoPlayer    文件:RxPermissions.java   
@TargetApi(Build.VERSION_CODES.M)
private Observable<Permission> requestImplementation(final String... permissions) {
    List<Observable<Permission>> list = new ArrayList<>(permissions.length);
    List<String> unrequestedPermissions = new ArrayList<>();

    // In case of multiple permissions,the observables are combined to have a unique response.
    for (String permission : permissions) {
        Log.i("","Requesting permission " + permission);
        if (isGranted(permission)) {
            // Already granted,subject);
        }

        list.add(subject);
    }

    if (!unrequestedPermissions.isEmpty()) {
        String[] unrequestedPermissionsArray = unrequestedPermissions.toArray(new String[unrequestedPermissions.size()]);
        requestPermissionsFromFragment(unrequestedPermissionsArray);
    }
    return Observable.concat(Observable.fromIterable(list));
}
项目:Phoenix-for-VK    文件:Dialogsstore.java   
Dialogsstore(@NonNull AppStores base) {
    super(base);
    this.updatePublishSubject = PublishSubject.create();
    this.dialogsDeletingPublisher = PublishSubject.create();
    this.preferences = base.getSharedPreferences("dialogs_prefs",Context.MODE_PRIVATE);
    this.unreadDialogsCounter = PublishSubject.create();
}
项目:jobson    文件:JobExecutorTest.java   
@Test
public void testExecuteEvaluatesToJSONFunctionAsExpected() throws InterruptedException {
    final JobExecutor jobExecutor = getInstance();
    final PersistedJob req =
            standardRequestWithCommand("echo","${toJSON(inputs)}");
    final atomicreference<byte[]> bytesEchoedToStdout = new atomicreference<>(new byte[]{});
    final Subject<byte[]> stdoutSubject = PublishSubject.create();

    stdoutSubject.subscribe(bytes ->
            bytesEchoedToStdout.getAndUpdate(existingBytes ->
                    Bytes.concat(existingBytes,MILLISECONDS);

    final String stringFromStdout = new String(bytesEchoedToStdout.get()).trim();

    assertthat(stringFromStdout).isEqualTo(toJSON(STANDARD_VALID_REQUEST.getInputs()));
}
项目:AndroidBlueprints    文件:Messageviewmodel.java   
@Inject
public Messageviewmodel(MessageRepository messageRepository,@Named("vm") Compositedisposable compositedisposable) {
    Timber.d("Init Messageviewmodel");
    this.repository = messageRepository;
    this.compositedisposable = compositedisposable;
    this.messageIdentifier = new Identifier();
    this.subject = PublishSubject.create();
    this.messages = new mutablelivedata<>();
}
项目:Phoenix-for-VK    文件:RealtimeMessagesProcessor.java   
RealtimeMessagesProcessor() {
    this.app = Injection.provideApplicationContext();
    this.repositories = Injection.provideStores();
    this.networker = Injection.provideNetworkInterfaces();
    this.publishSubject = PublishSubject.create();
    this.queue = new LinkedList<>();
    this.notificationsInterceptors = new SparseArray<>(3);
    this.ownersInteractor = InteractorFactory.createOwnerInteractor();
    this.messagesInteractor = InteractorFactory.createMessagesInteractor();
}
项目:grpc-mate    文件:ProductDao.java   
/**
 * Download product from given category.
 *
 * @param request               which contains query category
 * @param productPublishSubject the subject which downloaded product should publish to
 */
public void downloadProducts(DownloadProductsRequest request,PublishSubject<Product> productPublishSubject) {

  QueryBuilder queryBuilder = QueryBuilders.termQuery("category",request.getCategory());
  SearchResponse scrollResponse =
      esClient
          .prepareSearch(INDEX)
          .setScroll(DEFAULT_SCROLL_TIME_VALUE)
          .setTypes(TYPE)
          .setQuery(queryBuilder)
          .setSize(SCROLL_SIZE)
          .get();
  do {
    scrollResponse.getHits().forEach(hit -> {
      try {
        Product.Builder builder = Product.newBuilder();
        jsonParser.merge(hit.sourceAsstring(),builder);
        productPublishSubject.onNext(builder.build());
      } catch (IOException ioe) {
        // Don't fail the whole stream
        log.error("Unable to read product record",ioe);
        productPublishSubject.onError(ioe);
        throw new IllegalStateException(ioe);
      }
    });
    // Fetch next batch of cite group records
    scrollResponse =
        esClient
            .prepareSearchScroll(scrollResponse.getScrollId())
            .setScroll(DEFAULT_SCROLL_TIME_VALUE)
            .execute()
            .actionGet();
  } while (scrollResponse.getHits().getHits().length != 0);

  productPublishSubject.onComplete();
}
项目:grpc-mate    文件:ProductDaoTest.java   
@Test
public void calculateProductscore() throws Exception {
  PublishSubject<CalculateProductscoreResponse> publishSubject = PublishSubject.create();
  List<CalculateProductscoreResponse> responses = Lists.newArrayList();
  publishSubject
      .doOnNext(response -> responses.add(response))
      .subscribe();

  Product product = createProduct("category");
  productDao.calculateProductscore(product,publishSubject);

  assertthat(responses.size()).isEqualTo(1);
  publishSubject.onComplete();
}
项目:code-examples-android-expert    文件:lessonA_CreatingObservableStreams.java   
/**
 * Subjects can be both observables and observers
 * Registration of the subscribers is important,a observer is only be notified if
 * a new events occurs
 * */
@Test
public void useSubject() {
    Subject<String> subject = PublishSubject.<String>create().toSerialized();
    subject.subscribe(e-> result+=e);
    subject.onNext("Hello");
    subject.onNext("Man");
    subject.onNext("Test");

    subject.subscribe(e-> doIt());
    subject.onNext("Test");
    assertthat(result).isEqualTo(_____);

}
项目:RxNetWork    文件:RxBus.java   
/**
 * 接受消息
 *
 * @param tag      标志
 * @param callBack 回调
 */
public <T> disposableObserver register(@NonNull final Object tag,@NonNull final RxBusCallBack<T> callBack) {
    RxBusEvent rxBusEvent = rxBusEventArrayMap.get(tag);
    if (RxUtils.isEmpty(rxBusEvent)) {
        rxBusEvent = new RxBusEvent();
        rxBusEvent.subject = PublishSubject.create().toSerialized();
        rxBusEvent.disposable =
                rxBusEvent.subject
                        .ofType(callBack.busOfType())
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribeWith(new RxBusObserver<T>() {
                            @Override
                            public void onError(@io.reactivex.annotations.NonNull Throwable e) {
                                super.onError(e);
                                callBack.onBusError(e);
                            }

                            @Override
                            public void onNext(@io.reactivex.annotations.NonNull T t) {
                                super.onNext(t);
                                callBack.onBusNext(t);
                            }
                        });
        rxBusEventArrayMap.put(tag,rxBusEvent);
    }
    return rxBusEvent.disposable;
}

Objective-C 2.0 with Cocoa Foundation--- 6,NSObject的奥秘

Objective-C 2.0 with Cocoa Foundation--- 6,NSObject的奥秘

6,NSObject的奥秘

本系列讲座有着很强的前后相关性,如果你是第一次阅读本篇文章,为了更好的理解本章内容,笔者建议你最好从本系列讲座的第1章开始阅读,请点击这里。

在上一章里面,笔者向大家介绍了在Objective-C里面的几个非常重要的概念, 简单的说就是SEL,Class和IMP。我们知道Objective-C是C语言的扩展,有了这3个概念还有我们以前讲过的继承和封装的概念,Objective-C发生了翻天覆地的变化,既兼容C语言的高效特性又实现了面向对象的功能。

Objective-C从本质上来说,还是C语言的。那么内部究竟是怎样实现SEL,Class和IMP,还有封装和继承的?为了解答这个问题,笔者决定在本章向大家概要的介绍一下Objective-C的最主要的一个类,NSObject。

不过说实在话,如果同学们觉得本章的内容比较晦涩难懂的话,不阅读本章的内容丝毫不会对写程序产生任何不良的影响,但是如果掌握了本章的内容的话,对加深对Objective-C的理解,对于今后笔者将要讲述的内容而言,将会是一个极大的促进。 

6.1,本章程序的执行结果

在本章里面,我们将要继续使用我们在前面几章已经构筑好的类Cattle和Bull。由于在现在的Xcode版本里面,把一些重要的东西比如说Class的原型定义都放到了LIB文件里面,所以这些东西的具体的定义,对于我们来说是不可见的。

我们首先把第4章的代码打开,然后打开“Cattle.h” 文件,把鼠标移动到“NSObject”上面,单击鼠标右键,在弹出菜单里面选择“Jump to DeFinition”。然后会弹出一个小菜单,我们选择“interface NSObject” 。我们可以看到如下代码

@interface NSObject  < NSObject >  {
   Class       isa;

我们知道了,所谓的NSObject里面只有一个变量,就是Class类型的isa。isa的英文的意思就是is a pointer的意思。也就是说NSObject里面只有一个实例变量isa。好的,我们需要知道Class是一个什么东西,我们把鼠标移动到“Class”上面,单击鼠标右键,在弹出菜单里面选择“Jump to DeFinition”,我们看到了如下的代码:

typedef  struct  objc_class  * Class;
typedef 
 objc_object {
   Class isa;

*id;

... 

我们在这里知道了,Class实际上是一个objc_class的指针类型,我们把鼠标移动到“objc_class”上面,单击鼠标右键,在弹出菜单里面选择“Jump to DeFinition”,发现我们还是在这个窗口里面,Xcode并没有把我们带到objc_class的定义去,所以我们无从知道objc_class内部究竟是一个什么样的东西。

笔者顺便提一下,大家也许注意到了id的定义,id实际上是objc_object结构的一个指针,里面只有一个元素那就是Class。那么根据上面我们看到的,所谓的id就是objc_class的指针的指针。让我们回忆一下下面的代码:

id cattle  =  [Cattle  new ];

这句话是在初始化和实例话cattle对象,这个过程,实际上可以理解为,runtime为我们初始化好了Class的指针,并且把这个指针返回给我们。我们初始化对象完成了之后,实际上我们得到的对象就是一个指向这个对象的Class指针。 

让我们在回过头来说说这个神秘的Class,我们无法在Xcode里面看到Class也就是objc_class的定义。庆幸的是这部分的定义是GCC代码,是开源的。笔者下载了开源的代码之后,把开源的代码作了一些小小的调整,然后把Class的定义等等放到了我们的工程文件里面去,通过类型转化之后,我们终于可以看到Class,SEL,还有isa等等过去对我们来说比较“神秘”的东西的真正面目。

我们在前面几章里面在每一个章的第一节里面都要介绍一下本章程序执行结果的屏幕拷贝,本章也是一样,但是本章的执行结果非常简单。因为对于本章而言重点应该是放在对NSObject机制的理解上。

 

图6-1,本章程序运行结果

大家看到本章程序的运行结果的屏幕拷贝的时候,也许会觉得很无趣,因为单单从结果画面,我们没有发现任何令人感到很有兴趣的东西,相反,都是同学们已经很熟悉的一些老面孔。但是本章所要讲述的东西也许是同学们在其他语言里面从来没有遇到过的东西,这些东西将会令人感到新鲜和激动。

6.2,实现步骤

第一步,按照我们在第2章所述的方法,新建一个项目,项目的名字叫做06-NSObject。如果你是第一次看本篇文章,请到这里参看第二章的内容。

第二步,按照我们在第4章的4.2节的第二,三,四步所述的方法,把在第4章已经使用过的“Cattle.h”,“Cattle.m”,“Bull.h”还有“Bull.m” 导入本章的项目里面。如果你没有第4章的代码,请到这里下载。如果你没有阅读第4章的内容,请参看这里。

第三步,把鼠标移动到项目浏览器上面的“Source”上面,然后在弹出的菜单上面选择“Add”,然后在子菜单里面选择“New File”,然后在新建文件对话框的左侧最下面选择“Other”,然后在右侧窗口选择“Empty File”,选择“Next”,在“New File”对话框里面的“File Name”栏内输入“MyNSObject.h”。然后输入(或者是拷贝也可以,因为这是C的代码,如果你很熟悉C语言的话,可以拷贝一下节省时间)如下代码:

#include  stddef.h
typedef 
const    objc_selector 
{
    
void sel_id;
    
char sel_types;
MySEL;
typedef 
 my_objc_object {
    
 my_objc_class   class_pointer;
myId;
    
typedef myId (
MyIMP)(myId, MySEL, 

); 

    
typedef 
STR;                               /*  String alias  */
    
typedef 
 my_objc_class  MetaClass;
typedef 
MyClass;
 my_objc_class {     
    MetaClass           class_pointer;         
    
  super_class;            
    
         name;                 
    
long                 version;               
    unsigned 
       info;                  
    
                instance_size;          
    
 objc_ivar_list  ivars;              
    
 objc_method_list   methods;          
    
 sarray      dtable;                  
    
 subclass_list;           
    
 sibling_class;
    
 objc_protocol_list  protocols;         
    
 gc_object_type;
};
    
typedef 
 objc_protocol {
    
 class_pointer;
    
protocol_name;
    
protocol_list;
    
 objc_method_description_list  instance_methods,  class_methods; 
} Protocol; 
    
    
typedef 
 retval_t;        
typedef 
( apply_t)( );    
typedef union arglist {
    
arg_ptr;
    
 arg_regs[ sizeof  ( )];
arglist_t;            

typedef 
 objc_ivar  Ivar_t;
typedef 
 objc_ivar_list {
    
int    ivar_count;                             
    
 objc_ivar {
        
 ivar_name;                    
        
 ivar_type;                      
        
        ivar_offset;                           
    } ivar_list[
1 ];                              
} IvarList,0)">IvarList_t;

typedef 
 objc_method {
    MySEL         method_name;                  
    
 method_types;                 
    MyIMP         method_imp;                  
} Method,0)">Method_t;

typedef 
 objc_method_list {
    
  method_next;   
    
            method_count;              
    Method method_list[
];                   
} MethodList,0)">MethodList_t;

 objc_protocol_list {
    
next;
    size_t count;
    Protocol 
list[ ];
};

第四步,打开06-NSObject.m文件,输入如下代码并且保存

#import  Foundation / Foundation.h
#import 
" Cattle.h " Bull.h MyNSObject.h

 main (  argc,0)"> argv[]) {
    NSAutoreleasePool 
 pool   [[NSAutoreleasePool alloc] init];
    
    id cattle 
];    
    id redBull 
 [Bull  ];
    SEL setLegsCount_SEL 
 @selector(setLegsCount:);
    IMP cattle_setLegsCount_IMP 
 [cattle methodForSelector:setLegsCount_SEL];
    IMP redBull_setLegsCount_IMP 
 [redBull methodForSelector:setLegsCount_SEL];
    
    [cattle setLegsCount:
4 ];
    [redBull setLegsCount:
];
    [redBull setSkinColor:
@" red ];
    
    Class cattle_class 
 cattle -> isa;
    MyClass my_cattle_class 
isa;
    SEL say 
 @selector(saySomething);
    IMP cattle_sayFunc 
 [cattle methodForSelector:say];
    cattle_sayFunc(cattle, say);
    
    Class redBull_class 
 redBull isa;
    MyClass my_redBull_class 
isa;

    IMP redBull_sayFunc 
 [redBull methodForSelector:say];
    redBull_sayFunc(redBull, say);

    [pool drain];
    
return   0 ;
}

第五步,在06-NSObject.m文件的窗口的“[pool drain];”代码的左侧单击一下窗口的边框,确认一下是否出现一个蓝色的小棒棒,如果有的话那么断点被选择好了。如图6-2所示

 

 图6-2,选择执行断点

第六步,选择Xcode上面的菜单的“Run”,然后选择“Debuger” ,在Debuger窗口里面选择“Build and Go”。

好的,大家就停在这里,不要做其他的操作,我们把程序中断在程序几乎执行到最后的断点上,我们将要通过Debuger来看看Objective-C内部究竟发生了什么样的奇妙的魔法。

注意在从编译到执行的过程当中,会出现一些警告。由于本章程序指示用来阐述一些NSObject内部的东西,所以请忽略掉这些警告。当然,我们在写自己的程序的时候,编译产生的警告一般是不能被忽略的。

6.3,超类方法的调用

我们现在打开“06-NSObject.m”文件,发现下面的代码:

SEL setLegsCount_SEL   @selector(setLegsCount:);
IMP cattle_setLegsCount_IMP 
 [cattle methodForSelector:setLegsCount_SEL];
IMP redBull_setLegsCount_IMP 
 [redBull methodForSelector:setLegsCount_SEL];

这一段代码,对同学们来说不是什么新鲜的内容了,我们在第5章里面已经讲过,这个是SEL和IMP的概念。我们在这里取得了cattle对象和redBull对象的setLegsCount:的函数指针。

如果大家现在已经不在Debuger里面的话,那么请选择Xcode菜单里面的,“Run”然后选择“Debuger” 。

我们注意到在Debuger里面,cattle_setLegsCount_IMP的地址和redBull_setLegsCount_IMP是完全一样的,如图6-3所示:

图6-3,cattle_setLegsCount_IMPredBull_setLegsCount_IMP的地址。

注意由于环境和执行的时候的内存情况不同,所以同学们的电脑上显示的地址的数值可能和图6-3的数值不一样。
 

redBull_setLegsCount_IMP的地址完全一样,说明他们使用的是相同的代码段。这种结果是怎样产生的呢?大家请打开“MyNSObject.h”,参照下列代码:

    dtable;                  
      gc_object_type;
};

笔者在这里把开源代码的名字的定义加上了“my_”前缀,仅仅是为了区分一下。“MyNSObject.h”里面的代码问题很多,笔者从来没有也不会在实际的代码里面使用这段代码,使用这些代码的主要目的是为了向大家讲解概念,请大家忽略掉代码里面的种种问题。 

我们注意到这里的methods变量,里面包存的就是类的方法名字(SEL)定义,方法的指针地址(IMP)。当我们执行

IMP cattle_setLegsCount_IMP   [cattle methodForSelector:setLegsCount_SEL];

的时候,runtime会通过dtable这个数组,快速的查找到我们需要的函数指针,查找函数的定义如下:

__inline__ IMP
objc_msg_lookup(id receiver, SEL op)
{
  if (receiver)
   
 sarray_get(receiver class_pointer dtable, (sidx)op);
 
else
   
 nil_method;

好的,现在我们的cattle_setLegsCount_IMP没有问题了,那么redBull_setLegsCount_IMP怎么办?在Bull类里面我们并没有定义实例方法setLegsCount:,所以在Bull的Class里面,runtime难道找不到setLegsCount:么?答案是,是的runtime直接找不到,因为我们在Bull类里面根本就没有定义setLegsCount:。

但是,从结果上来看很明显runtime聪明的找到了setLegsCount:的地址,runtime是怎样找到的?答案就在:

  super_class;            

在自己的类里面没有找到的话,runtime会去Bull类的超类cattle里面去寻找,庆幸的是它成功的在cattle类里面runtime找到了setLegsCount:的执行地址入口,所以我们得到了redBull_setLegsCount_IMP。 redBull_setLegsCount_IMPcattle_setLegsCount_IMP都是在Cattle类里面定义的,所以他们的代码的地址也是完全一样的。

我们现在假设,如果runtime在cattle里面也找不到setLegsCount:呢?没有关系,cattle里面也有超类的,那就是NSObject。所以runtime会去NSObject里面寻找。当然,NSObject不会神奇到可以预测我们要定义setLegsCount:所以runtime是找不到的。

在这个时候,runtime 并没有放弃最后的努力,再没有找到对应的方法的时候,runtime会向对象发送一个forwardInvocation:的消息,并且把原始的消息以及消息的参数打成一个NSInvocation的一个对象里面,作为forwardInvocation:的唯一的参数。 forwardInvocation:本身是在NSObject里面定义的,如果你需要重载这个函数的话,那么任何试图向你的类发送一个没有定义的消息的话,你都可以在forwardInvocation:里面捕捉到,并且把消息送到某一个安全的地方,从而避免了系统报错。

笔者没有在本章代码中重写forwardInvocation:,但是在重写forwardInvocation:的时候一定要注意避免消息的循环发送。比如说,同学们在A类对象的forwardInvocation里面,把A类不能响应的消息以及消息的参数发给B类的对象;同时在B类的forwardInvocation里面把B类不能响应的消息发给A类的时候,容易形成死循环。当然一个人写代码的时候不容易出现这个问题,当你在一个工作小组里面做的时候,如果你重写forwardInvocation:的时候,需要和小组的其他人达成共识,从而避免循环调用。

6.4,重载方法的调用

让我们继续关注“06-NSObject.m”文件,请大家参考一下下面的代码:

 1  Class cattle_class  isa;
 2  MyClass my_cattle_class   3  SEL say   @selector(saySomething);
 4  IMP cattle_sayFunc   [cattle methodForSelector:say];
 5  cattle_sayFunc(cattle, say);
 6      
 7  Class redBull_class   8  MyClass my_redBull_class   9 
10  IMP redBull_sayFunc   [redBull methodForSelector:say];
11  redBull_sayFunc(redBull, say);

本节的内容和6.3节的内容比较类似,关于代码部分笔者认为就不需要解释了,如果同学们有所不熟悉的话,可以参考一下第5章的内容。

在我们的Cattle类和Bull类里面,都有saySometing这个实例方法。我们知道只要方法的定义相同,那么它们的SEL是完全一样的。我们根据一个SEL say,在cattle和redBull对象里面找到了他们的函数指针。根据6.3节的讲述,我们知道当runtime接收到寻找方法的时候,会首先在这个类里面寻找,寻找到了之后寻找的过程也就结束了,同时把这个方法的IMP返回给我们。所以,在上面的代码里面的cattle_sayFuncredBull_sayFunc应该是不一样的,如图6-4所示:

 

图6-4, redBull_sayFunc的地址

6.5,超类和子类中的Class 

在类进行内存分配的时候,对于一个类而言,runtime需要找到这个类的超类,然后把超类的Class的指针的地址赋值给isa里面的super_class。所以,我们的cattle里面的Class应该和redBull里面的Class里面的super_class应该是完全相同的,请参照图6-5:

 

图6-5, cattle里面的Class和redBull里面的Class里面的super_class

6.6,实例变量的内存分配的位置

我们先来回忆一下对象是怎样被创建的。创建对象的时候,类的内容需要被调入到内存当中我们称之为内存分配(Allocation),然后需要把实体变量进行初始化(Initialization),当这些步骤都结束了之后,我们的类就被实例化了,我们把实例化完成的类叫做对象(Object)。

对于内存分配的过程,runtime需要知道分配多少内存还有各个实例变量的位置。我们回到“MyNSObject.h”,参照如下代码:

 Ivar_t;
2   objc_ivar_list {
3          ivar_count;                             
4   objc_ivar {
5            ivar_name;                    
6   ivar_type;                      
7          ivar_offset;                           
8      } ivar_list[ ];                              
9  } IvarList,0)">IvarList_t;

我们仔细看看第5行的ivar_name,顾名思义这个是实例变量的名字,第6行的ivar_type是实例变量的类型,第7行的ivar_offset,这个就是位置的定义。runtime从类的isa里面取得了这些信息之后就知道了如何去分配内存。我们来看看图6-6:

 

图6-6,实例变量在内存中的位置

在cattle里面,我们看到了第一个实例变量是isa,第二个就是我们定义的legsCount。其中isa是超类的变量,legsCount是Cattle类的变量。我们可以看出来,总是把超类的变量放在前头,然后是子类的变量。

那么对于redBull而言是什么样子呢?我们来看看图6-7


图6-7,redBull里面的实例变量的位置

我们通过图6-7可以发现redBull的Class里面的skinColor的位置偏移是8,很明显,runtime为isa和legsCount预留了2个位置。

6.7本章总结

非常感谢大家!

在本章里面,笔者通过一个小小的“把戏”为同学们揭开了NSObject的神秘的面纱。本章的内容,虽然对理解Objective-C不是必需的,但是对以后的章节的内容的理解会有一个非常好的辅助作用,希望同学们花费一点点心思和时间阅读一下。

另外,笔者需要再次强调一下,由于笔者没有得到官方的正式的文档说明,所以不能保证本章的内容是完整而且准确的,本章内容仅供大家参考和娱乐,希望大家谅解。

今天的关于objective-c – 在Sublime Text 2中获取Cocoa方法完成获取object的key的分享已经结束,谢谢您的关注,如果想了解更多关于cocoa – 使用NSManagedObjectContext的objectWithID的“正确”方法是什么:、io.reactivex.subjects.CompletableSubject的实例源码、io.reactivex.subjects.PublishSubject的实例源码、Objective-C 2.0 with Cocoa Foundation--- 6,NSObject的奥秘的相关知识,请在本站进行查询。

本文标签: