Are These Two Instance of the Same Class? (ReactiveCocoa Documentation Examples) - objective-c

I don't understand where the RACSignal object comes from in the following example in the ReactiveCocoa github documentation.
Under Parallelizing independent work, it first shows the classic objective-c version:
__block NSArray *databaseObjects;
__block NSArray *fileContents;
NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
NSBlockOperation *databaseOperation = [NSBlockOperation blockOperationWithBlock:^{
databaseObjects = [databaseClient fetchObjectsMatchingPredicate:predicate];
}];
Clearly, [databaseClient fetchObjectsMatchingPredicate:predicate] returns an array. But, in the reactive version:
RACSignal *databaseSignal = [[databaseClient
fetchObjectsMatchingPredicate:predicate] // <== this should also be an array
subscribeOn:[RACScheduler scheduler]]; // ,<== subscribeOn: is a RACSignal Method only
... it looks like the same method is supposed to return not an array (which would have a rac_sequeance attribute) but a RACSignal.
In this example, is it meant to be read that `databaseClient' class in the RAC example is actually a subclass of RACSignal? Or, is a signal being created in some way not shown?
Currently running MacOS 10.9.3 with Reactive Cocoa 2.3. Documentation is from the ReactiveCocoa 3.0 branch.

It's fairly idiomatic in ReactiveCocoa code to name a method that returns a signal in a similar fashion to a method that would return the value directly. In other words, even though the method that returns the signal doesn't actually perform the action directly (when the method is executed), it's given a method name that suggests that it does.
For example, a method that queries a database and returns the result of that query directly might be named like this:
- (DBResult *)queryDatabase:(DBQuery *)query;
Whereas a RAC-ified version of this method would probably be named like this:
- (RACSignal *)queryDatabase:(DBQuery *)query;
It might seem a bit unintuitive at first, because technically that method doesn't query the database – instead, it returns a signal that results in an action to query the database when the signal is subscribed to – but that's the convention. You don't have to observe the convention in your own code, but a perusal of the OctoKit source code will show you that it's not uncommon.
In this example, is it meant to be read that databaseClient class in the RAC example is actually a subclass of RACSignal? Or, is a signal being created in some way not shown?
In this example, databaseClient is not a subclass of RACSignal. It is just an object that responds to the -fetchObjectsMatchingPredicate: message, and returns a RACSignal from the corresponding method. Hypothetically, the object's class might look something like:
#interface MyDatabaseClient : NSObject
- (RACSignal *)fetchObjectsMatchingPredicate:(NSPredicate *)predicate;
#end

Related

How to properly use makeObjectsPerformSelector: Getting error unrecognized selector

Let me start off by saying I am new to Objective C.
I am getting the error
atusMenuApp[24288:303] -[__NSCFConstantString createListItem]: unrecognized selector sent to instance 0x100002450
Here is my code:
selector = [NSMutableArray arrayWithObjects: #"nvda", #"aapl", #"goog", nil];
[selector makeObjectsPerformSelector:#selector(createListItem:) withObject:self];
- (void)createListItem:(NSString *)title {
//do some stuff
}
Now I have done plenty of looking around and it seems like the biggest reason for this issue is the addition of or lack of the :however I do believe I properly have that in place. Maybe I do not understand the use of makeObjectsPerformSelector very well as after look up the doc on it I found:
Sends to each object in the array the message identified by a given selector, starting with the first object and continuing through the array to the last object.
Any help would be great, Thanks!
[Only if you read the documentation (or thought a bit about why a method is named this way and not that), or even made the effort trying to understand the error message...]
The makeObjectsPerformSelector:withObject: method of NSArray does what it suggests it does: it makes the objects of the array perform the selector, that can have an optional argument. So
[selector makeObjectsPerformSelector:#selector(createListItem:) withObject:self];
will send the createListItem: message to every single NSString object in the selector array and pass in self as its argument. It won't perform the selector on self passing in the object. I. e., what you have is equivalent to
for (NSString *obj in selector) {
[obj createListItem:self];
}
Obviously, instead of this, you want the following:
for (NSString *obj in selector) {
[self createListItem:obj];
}
You don't even need that nasty method for this. A nice fast enumeration for loop will do it.
First you make an array of NSStrings. Then, you send them all the message createListItem. That's all fine and dandy, but NSString doesn't have any method called createListItem; just because you've defined an instance method called createListItem doesn't mean every instance of every class can use it. Only the class who's implementation file has the definition will be able to handle the message. For instance, I can't make a list of Car instances, then define the method fly in another class called Helicopter's implementation and expect to be able to call fly on an instance of Car; only Helicopter can use it. I recommend you read a good book on Objective-C and further familiarize yourself with classes, instances and instance methods.
You misunderstood the method.
It will call the method createListItem: with argument self over every object of the NSArray.
So the resulting call would be something like:
[#"nvda" createListItem:self];
...
Clearly that method doesn't exist for a NSString and there goes your exception.
If you need to apply a method of self to every object inside your array, simply loop through it.

Declaring and implementing a method that itself executes one line of code

I've many times seen a case where a programmer needs to assign some value (Object or primitive type, does not matter). And let's say this value is an NSString and can be obtained from the following expression
[myObject description]// returns NSString
But for some reason I've seen many people declare another method that itself returns an NSString and executes the above command only. Like:
-(NSString*)getDescription{
return [myObject description];
}
Is this just a matter of preference, or is is there some benefit from it?
Is this just a matter of preference, or is is there some benefit from it?
Those one line wrappers are often used to:
introduce behavior of a method that is meant to be overridden
or (more frequently) to simplify the program. If the method did not exist, you may find the complexity of the program grows. It serves to demonstrate intent, for clarity, documentation, and to minimize redundant implementations (simplifying the program).
There is definitely some "benefit" of creating a method or even better, overriding the "standard" NSObject description method..
If you have a custom NSObject for example and override the +(NSString *)description method you can then return information directly inside that object.
Take for example the following was overwritten in the NSObject we called foo.
+ (NSString *)description {
return #"Hello there";
}
Now, if you ever called [foo description] it would return the string "Hello there".
However, if you just returned description without overwriting the description method, it'd return something like <foo>0x12234 or something.
So yeah, it definitely has a lot of benefit to overriding a custom NSObject description.

Why create custom init when ivars/properties can be set from outside the instance?

I'm reading an Objective-C book and I have a question that the book doesn't seem to really answer.
Let's say I have two custom-made classes.
The first class is called ClassA. It has both the .h and .m files of course. The second class is called ClassB. It also has both .h and .m files.
Somewhere in the code, 'ClassA' has this method:
-(IBAction)displaySomeText:(id)sender {
ClassB *myNumber = [[ClassB alloc]init];
NSString *numberString = [myNumber storedNumberAsString];
// storedNumberAsString is just a method that returns a string object that holds
// myVariable.
[textView insertText:numberString];
//textView is a object I created that just displays some text on screen.
[myNumber release];
}
The book tells me that ClassB should have a method:
-(id)init {
[super init]; //I know why this is done, the book explains it well.
myVariable = 42; // I created this variable already in the ClassB .h file
return self;
}
Now, when in the Interface Builder I click the buttons I connected, etc. It works, the number displayed is 42.
My question is, why do I have to create an -(id)init method for ClassB, if I can do the following in ClassA's method:
-(IBAction)displaySomeText:(id)sender {
ClassB *myNumber = [[ClassB alloc]init];
myNumber.myVariable = 42; //I just do this to skip the -(id)init method.
NSString *numberString = [myNumber storedNumberAsString];
[textView insertText:numberString];
[myNumber release];
}
Doing this, it still displays the same value: 42. I can change it to whatever I like. So why not just use the init inherited from NSObject and just do the simple way myNumber.myVariable = 42?
Suppose that the value of the instance variable were something more complicated than an integer. Suppose it involved reading a string from a file, or getting some information over the network, or just doing some arithmetic. In that case, it wouldn't make sense to have ClassA be responsible for setting that value correctly. That would break the encapsulation that makes it useful to have separate classes in the first place.
In this extremely simple case, you're quite right, there may be no reason to have a custom initializer for ClassB, but in general, a class should itself be responsible for its state being set up correctly. Foisting that responsibility off on other classes means that those others need to know about the internals of the first, meaning the two may be too tightly coupled.
In some cases, the value of the ivar might be a piece of information that is known only to ClassA, or needs to be calculated based on such a piece of information. Then you should create a custom initializer for ClassB which receives that value, e.g., - (id) initWithInteger: This would become the "designated initializer", and you would then override -[ClassB init] to call it with some reasonable default value.
If instances of ClassB do not have to have anything initialized (other than to nil/zero), you do not need to create an explicit init method for ClassB. In this case the question is whether setting myVariable to 42 is ClassB's answer to life, the universe, and everything, or whether myVariable is just a field in ClassB that could be set to any value.
That is, the issue is conceptual, not of physical significance. If conceptually the value 42 "belongs" to ClassB, then there should be an init method for ClassB that sets it. If that specific value has more meaning to ClassA than to ClassB then some method of ClassA should set it. If you do it "wrong" the code still works fine, but your design is slightly less elegant, slightly less extendable, slightly less robust.
This is kind of a tricky issue. I was "brought up" to think that after a constructor (initializer) runs, the object should be ready to go. You should be able to safely call any method on it. Therefore, you need to set up any instance variables in the constructor for which 0 is not a valid value. I like to set them up if they have 0 values anyway, just for sanity, because I never want to bother to know the minute details of every language I work with, like whether they initialize instance variables to 0 automatically.
However, there are some arguments for not initializing some variables.
The initialization is complex, like loading a file or getting data from the network. You want to keep open the possibility of creating an instance and waiting until you're ready to do heavy weight operations.
There are quite a lot of instance variables that are configurable. Your options are to make a constructor with umpteen arguments, or make a constructor with no or a few arguments, and let the caller decide which values should be set to non-default values by property setters.
You need to set up a whole object graph before you can meaningfully initialize a value. That is, initializing the value might have side effects that depend on other related objects. The best solution is to construct each object, then use property setters to set the relationships between objects, then use property setters to initialize attribute values.

Encoding an Objective-c Block?

Is it possible to encode an Objective-C block with an NSKeyedArchiver?
I don't think a Block object is NSCoding-compliant, therefore [coder encodeObject:block forKey:#"block"] does not work?
Any ideas?
No, it isn't possible for a variety of reasons. The data contained within a block isn't represented in any way similar to, say, instance variables. There is no inventory of state and, thus, no way to enumerate the state for archival purposes.
Instead, I would suggest you create a simple class to hold your data, instances of which carry the state used by the blocks during processing and which can be easily archived.
You might find the answer to this question interesting. It is related.
To expand, say you had a class like:
#interface MyData:NSObject
{
... ivars representing work to be done in block
}
- (void) doYourMagicMan;
#end
Then you could:
MyData *myWorkUnit = [MyData new];
... set up myWorkUnit here ...
[something doSomethingWithBlockCallback: ^{ [myWorkUnit doYourMagicMan]; }];
[myWorkUnit release]; // the block will retain it (callback *must* Block_copy() the block)
From there, you could implement archiving on MyData, save it away, etc... The key is treat the Block as the trigger for doing the computation and encapsulate said computation and the computation's necessary state into the instance of the MyData class.

Using -performSelector: vs. just calling the method

I'm still kind of new to Objective-C and I'm wondering what is the difference between the following two statements?
[object performSelector:#selector(doSomething)];
[object doSomething];
Basically performSelector allows you to dynamically determine which selector to call a selector on the given object. In other words the selector need not be determined before runtime.
Thus even though these are equivalent:
[anObject aMethod];
[anObject performSelector:#selector(aMethod)];
The second form allows you to do this:
SEL aSelector = findTheAppropriateSelectorForTheCurrentSituation();
[anObject performSelector: aSelector];
before you send the message.
For this very basic example in the question,
[object doSomething];
[object performSelector:#selector(doSomething)];
there is no difference in what is going to happen. doSomething will be synchronously executed by object. Only "doSomething" is a very simple method, that does not return anything, and does not require any parameters.
were it something a little more complicated, like:
(void)doSomethingWithMyAge:(NSUInteger)age;
things would get complicated, because
[object doSomethingWithMyAge:42];
can no longer be called with any variant of "performSelector", because all variants with parameters only accept object parameters.
The selector here would be "doSomethingWithMyAge:" but any attempt to
[object performSelector:#selector(doSomethingWithMyAge:) withObject:42];
simply won't compile. passing an NSNumber: #(42) instead of 42, wouldn't help either, because the method expects a basic C type - not an object.
In addition, there are performSelector variants up to 2 parameters, no more. While methods many times have many more parameters.
I have found out that although synchronous variants of performSelector:
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
always return an object, I was able to return a simple BOOL or NSUInteger too, and it worked.
One of the two main uses of performSelector is to compose dynamically the name of the method you want to execute, as explained in a previous answer. For example
SEL method = NSSelectorFromString([NSString stringWithFormat:#"doSomethingWithMy%#:", #"Age");
[object performSelector:method];
The other use, is to asynchronously dispatch a message to object, that will be executed later on the current runloop. For this, there are several other performSelector variants.
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
- (void)performSelector:(SEL)aSelector target:(id)target argument:(id)arg order:(NSUInteger)order modes:(NSArray *)modes;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;
(yes I gathered them from several Foundation class categories, like NSThread, NSRunLoop and NSObject)
Each of the variants has its own special behavior, but all share something in common (at least when waitUntilDone is set to NO). The "performSelector" call would return immediately, and the message to object will only be put on the current runloop after some time.
Because of the delayed execution - naturally no return value is available form the method of the selector, hence the -(void) return value in all these asynchronous variants.
I hope I covered this somehow...
#ennuikiller is spot on. Basically, dynamically-generated selectors are useful for when you don't (and usually can't possibly) know the name of the method you'll be calling when you compile the code.
One key difference is that -performSelector: and friends (including the multi-threaded and delayed variants) are somewhat limited in that they are designed for use with methods with 0-2 parameters. For example, calling -outlineView:toolTipForCell:rect:tableColumn:item:mouseLocation: with 6 parameters and returning the NSString is pretty unwieldy, and not supported by the provided methods.
Selectors are a bit like function pointers in other languages. You use them when you don't know at compile time which method you want to call at runtime. Also, like function pointers, they only encapsulate the verb part of invocation. If the method has parameters, you will need to pass them as well.
An NSInvocation serves a similar purpose, except that it binds together more information. Not only does it include the verb part, it also includes the target object and the parameters. This is useful when you want to call a method on a particular object with particular parameters, not now but in the future. You can build an appropriate NSInvocation and fire it later.
There is another subtle difference between the two.
[object doSomething]; // is executed right away
[object performSelector:#selector(doSomething)]; // gets executed at the next runloop
Here is the excerpt from Apple Documentation
"performSelector:withObject:afterDelay:
Performs the specified selector on the current thread during the next run loop cycle and after an optional delay period. Because it waits until the next run loop cycle to perform the selector, these methods provide an automatic mini delay from the currently executing code. Multiple queued selectors are performed one after another in the order they were queued."