This post was conceived after some important questions were not answered clearly. I do not pretend to become a cool programmer. No, everything is still ahead, but the incubation period has already passed. This is an article from the series "You Can't Do It Yourself - Teach the Other." In a sense, in order to understand something better, you need to explain something to someone. Moped is not mine, this phrase I met earlier in publications on Habré. Some things are very difficult to understand. And people who understand, usually can not explain to a beginner. Maybe it is waiting for me too. It's like a conversation between an adult and a child. Almost a generational conflict. While my level is not turned into a professional, you need to set out my current vision.
In the article, the terms used in the explanation of various concepts are quoted. The article is written for people who have already learned how to distinguish loops from arrays and understand what a function and method are.
If you have never programmed, then the book by Kernighan and Ritchie (in any edition), you obviously will not be able to do. In nature, there is no such force of will that could make you finish reading a book to the end, while solving all the above problems.
I highly recommend BecomeAnXcoder. Everything is written there quite clearly for people who know very little about programming. The information is a little outdated, but it will do for a start. Maybe it already caught your eye, or you even downloaded it, but put it in a directory with literature (well, everyone has such a directory, it takes dozens of gigabytes, and we are going to read all this as soon as free time appears, and the directory is growing ... ).
It is clear that the best option - MAC. At worst - Hakintosh or a virtual machine. And even if the processor does not allow you to run anything from the above, you can start right in notepad, followed by compilation in the command line.
In many forums, you can find a popular question asked by people who appear to be in a heavily armored tank: "Does the Objective-C programmer need to learn the actual C?". Everywhere they write the same thing. Those who are more generous and started with structured programming - they say that it is just necessary to become at least MiddleDeveloper in C, and only then look for a way in the wilds of the PLO, which is Objective-C. Those who did not know C, but already somehow achieved the status of Middle Developer, object: they say, learn how the buttons on the iPhone are drawn and how they assign the function, and the materiel will be pulled up as needed. I categorically declare that learning how buttons are assigned functions, not programming! I do not urge to spend half a year on the understanding of pure C. But a couple of weeks - a month is worth paying. This will give some background to your ambitions. As we learn Objective-C, such code structures will necessarily arise that nothing will be clear. Therefore, I suggest, without any fanaticism, but to get acquainted in detail with the book of Krupnik AB "Learning C". It is 3 times more than the previous one in volume, but it is read easily and naturally. The book again, at a fairly affordable level, explains the basic basics of programming. In it you can learn how to distinguish an array from a loop and what pointers are.
Recently on Habré flashed an article where the author cited a lot of literature, which he advised to read and go to work as a junior for bread. If you simply read all the literature cited in that article, you will not learn anything, and if you can solve and memorize all the literature again, then you will not be able to walk as a junior, but as a solid developer.
Start: class method and instance method
What is a method? This is a set of commands / instructions or one command / instruction that can be applied to an object and calls the necessary processes in it. If this is not entirely clear, then read on and understand. In fact, it is hard to understand what a class method and an instance method are. Everyone says: “with a“ + ”sign is a class method, but with a“ - “sign, it is an instance method. Do you understand? ”And in response, they heard:“ Yes, the class method and the instance method. ” At first, I personally understood only that they were different, but what and when to use was not clear. Wikipedia stubbornly repeats the same thing that we have heard and read.
In the vast majority of cases, you will work with instance methods.
So, the instance method. Imagine that we have a program in which we will use 2 classes: Primus and Kitchen.
Any class (except abstract) has methods and / or functions. A class can have several methods with a "+" sign in front of the method name (class method) and several methods with a "-" sign in front of the method name (instance method). Here are the methods that with the sign "-" we actively apply to objects - instances of a class and the class itself. And methods with a “+” sign can only be applied to the class itself, where this method was declared.
What is a class instance?
It sounds proudly, but incomprehensible. Who remembers from the school course: in geometry, a point is a parent for a circle, a straight line, and other figures, because each figure consists of a set of points.
A class for Objective-C, interpreted as an object on some resources and vice versa. In fact, this is a bit like that. We can say that an object is an instance of a class. As a specific instance of a primus standing in your kitchen, this is an instance of the Primus type: with twisters, a burner, etc. This is not just a primus — it is your primus. The class is an example to follow. The sample is the standard of something that can also perform some functions due to the methods of the class (with a "+" sign).
Here you can read a little more detailed.
There are also “protocols” and “abstract classes”. It is more and more interesting here, but the threshold of understanding is higher than that of a class and an object. The difference is that the "protocol" cannot have a subclass or a child object inherit it, it needs to match. As required by recruitment. The use of protocols in real life, I will address in this article. An abstract class is an entity that is like a class, but not an entirely concrete class, therefore an abstract one. For example, again, your home primus is a copy of the Primus class, and not of some abstract class Heater. You cannot have a heater without a clan or tribe at home (it can also be a fireplace and a battery). In this way, the Primus class can be the successor of the Heater abstract class. And your primus is already a copy of the specific definition of a primus. And for his attributes - properties, methods, protocols, when used, he refers to his class and verifies what he can do that he cannot and what he may even have available.
Imagine that there is a certain class "Gas burner" - the heir of the abstract class "heater". The “Gas Burner” class will be the parent for the Primus and the Gas Stove. In order to get closer to programming, you need to abstract a little.
In Objective-C, there is a parent class NSObject. In a programming language, it is like a point in geometry. This is an ideal class: there is nothing superfluous in it, it does anything concrete, but anything can be created from it. Such is the brick of the universe. If in Xcode you hold down the “Command” button and click on NSObject, then the contents of the file NSObject.h will open before you. It contains about 200 lines of descriptions of various methods. There are both methods with a "+" sign in front of the name, as well as methods with a "-" sign. The essence of the methods with a “+” sign is such that they can only be applied directly to the NSObject itself. This method is, for example,
')
+(id) alloc;
and it can only be used this way:
[NSObject alloc];
Any other object in Objective-C is by definition a descendant of NSObject. It implements additional methods that give it personality traits. Suppose this is an NSResponder. This child, NSResponder, can also have child objects. For example, UIView. Further on the inheritance tree, you can take UIScrollView as an example. Then - UITableView. In each case, the descendants acquire additional functionality. In addition to being able to do something of their own, an individual, they can do everything that their ancestor can do. This is
inheritance .
If you do not want your descendant class to exactly copy the behavior of the parent class, then you can redo any method of the class - the parent according to your taste. This is
polymorphism .
In your programs, you will take the class you need and add the necessary methods to it - to expand its functionality. You can also take the class you created and make it a descendant, again expanding the functionality and at the same time creating a unique tool to solve the desired task. The described mechanism is called the creation of subclasses "subclass".
I will not go into the broad descriptions of methods with a "+" sign. It will be clearer to show that the application of the method
+(id) alloc;
to any class or subclass allocates for it the necessary amount of memory in the computer's RAM.
NSObject *object = [NSObject alloc];
Application of the method
-(id) init;
initializes the object, allocates a place for it in the RAM, and then the object itself begins to exist and you can work with it.
NSObject *object = [[NSObject alloc] init];
These 2 methods ("alloc" and "init") have just created an object. And this object is an instance of an object or an instance of the class NSObject. If you apply these methods separately
NSObject *object = [NSObject alloc]; [object init];
then the object will also be created. But there is a non-zero probability that you will create the wrong object that has been allocated memory. Suppose a method call
NSObject *object = [NSObject alloc];
allocated such an address in his memory
0x000000000
This happens because during initialization, the executable environment, all objects are set to "nil" to avoid a reference to a place in memory filled with "garbage". Or links to another specific object, which in fact is also already “garbage”, because it has completed its life cycle and is no longer “stored” in memory, but simply “is”. In order to understand what is "garbage", create a simple program in which you declare
int i;
without assigning it a value, and then output its value to the console
NSLog(@"%i", i);
You will be surprised at what your “i” is like.
An instance of the isa object will also be created, which will be discussed later. This is the only non-zero pointer when creating your object. Suppose it is a thread to the parent object, which will generate its own instance and give life to our object.
That is, theoretically, the object is already there after applying the “alloc” method. But he can not pass the test
if (!self){ ... }
Such a piece of code can be seen in any template object in the "init" method or its derivatives.
In this case, the object seems to be as it is, but in principle it is equal to "nil". An object that is not initialized is like a machine that you are only going to buy on credit. It seems like it is, but it is not yours. And if you can use the "init" method without departing from the cash register
NSObject *object = [[NSObject alloc] init];
then “Bingo!”, and the object belongs to you, you can do whatever you want with it. But if you apply a method to it
[object init];
then another object can be initialized. It seems like you paid off a loan for a car, but it turned out that the wrong car and you get another car instead of one. They are at first glance indistinguishable from each other. But they have different VIN numbers, which means that when checking at a traffic police station you will be told that the car is not yours. Below is an augmented explanation of this phenomenon.
As you already understood the "+ alloc" method is a class method, and the "-init" method is an instance method.
I will give an example with real things.
Full implementation of the method usually includes 2 files with the extensions * .h and * .m. There are other quantities, depending on what kind of class it is and what goals it pursues.
Your program has a class "Primus". In the file "Primus.h" methods are declared:
Primus. h
The program also has the class "Kitchen", where in the file "Kitchen.h", the methods are declared:
Kitchen.h
In the files "Primus.m" and "Kitchen.m" all the declared methods must be implemented, that is, described: how and what happens in each method.
If you are going to create an instance of another class in any class, you will need to import the * .h file of the object being created in the header, for example, in the header of the Kitchen.h file we will enter
#import "Primus.h"
That is, it will be possible to create a class “Primus” inside the class “Kitchen”.
Since we imported the header file Primus.h into the file Kitchen.h, in the class Kitchen we got access to those methods of the instance of the class Primus, which are declared in the file Primus.h. They can be applied either in relation to the class or to an instance of the class “Primus”.
In the Primus.m file, it is necessary to implement all the methods that were declared in the Primus.h file, but also in it you can implement any method not declared in the header file Primus.h. This method will be available only from inside the class and cannot be called in another class in the program. You can also create variables inside the Primus.m file — they will also not be available for external use. They simply do not know about them. Therefore, a file of type * .h is called a class interface. Only that which is clearly indicated in it is accessible from the outside to the class in which it is written
#import "Primus.h"
. The unavailability of methods and variables for other parts of the program is called
encapsulation .
First, let's create an instance of the Primus class inside the Kitchen class.
Primus *myPrimus = [Primus hotAsHell];
As you can see, we are sending the c "+" method not to an instance of the class “myPrimus”, but directly to the class “Primus”. An instance of the Primus class called myPrimus has been created. Further, the methods from “Primus.h” with the “-” sign will be applied to the instance of the class - “myPrimus”. And if we want to create a new copy of the Primus class, then we can again use the "+ hotAsHell" method. Also in the Primus class there is a method
-(id) initWithGas:(Gas *)gas temperature:(NSInteger)t;
Usually, all methods that start with “init” do the same thing as the “init” method of the NSObject class, but with advanced features. And in this case, the use of the "init" method from this angle
Primus *myPrimus = [[Primus alloc] initWithGas:Propan temperature:750];
will create a new object of the Primus class with unique characteristics.
In the example just described, the method with arguments was applied. In this particular case, it is used to create an instance of the Primus class with clearly defined characteristics. The name of the characteristics shows that this copy of the Primus class will run on Propan gas and at a temperature of 750 degrees.
Note that the names of methods in Objective-C are quite meaningful. At times, you will be amazed at their names consisting of 10 words, but this contributes to a better understanding of what is written. Roughly speaking, the code is self-documenting. Which of course does not exclude the need to write comments. But if we make it a rule to create our own methods, the name of which will carry the meaning and relate to the creation of variables in the same way, the number of comments in the code can be significantly reduced.
Unlike some other programming languages ​​in Objective-C, the methods are not called, but are sent to objects. Thus, this PL refers to the “message oriented language”, it does not sound so strict in Russian, so the translation is not provided.
Also note that all methods that, after sending to an object, create (return) a new object have in parentheses after "+" or "-" either the specific name of the object for which they will return an instance, or "id". That is, according to which object is indicated in brackets immediately after the “+” or “-” sign, we can judge what we get after sending this method. What is an “id”? This is a type of object that can take the form (type) of any other object. Let's say this is a “weak” type of object. Not in the sense that something is "weak." If to speak the generally accepted concepts, this is a weakly typed object. The presence of such objects in the PL makes it weakly typed.
It is also possible to detect the type “void” in these brackets.
What is "void"?
Everyone says: "This is when the method returns nothing." And why is it needed? The application of this type of method still produces manipulations with objects, structures and numbers. Also, objects and scalar values ​​that fall into it as arguments can change or disappear altogether. It all depends on what is implemented within each specific method. The fact is that "void" does not return anything ... new. As it was said, the arguments that got into it can change themselves, or influence other objects that are manipulated in the “void” method. He may even create new objects within himself, but nothing comes out explicitly. Usually a method that returns something has the keyword “return” at the very end. And the method of the type "void", "return" at the end does not have. He can have it within his own cycles or conditions in order to be able to interrupt them in the right place. But not at the end. The method does not create anything fundamentally new; it simply works with a pointer to an object (number, array, cell, etc.), changes data at this address, or applies them to calculate other data that it assigns to other objects.
What is “self”?
This word is often used anywhere. The very fact of its use in various places, confuses the harmonious pantries of your knowledge.
Let's return to the classes “Primus” and “Kitchen”. Take a specific method of the Primus class and consider how its implementation will look like in the Primus.m file. For example, this is a method.
-(void) doFireWithGas:(Gas *)gas;
can be implemented like this:
-(void) doFireWithGas:(Gas *)gas { id myPrimus; if (!self){ myPrimus = [self initWithGas:gas temperature:750]; } ... ... ... }
In curly braces, implementation or “implication” of the method occurs. In this case, the implementation of the method reads like this: if not myPrimus, then execute the command
[self initWithGas:propan temperature:750];
which in turn reads like: initialize yourself with gas: gas temperature: 750. That is, the method is sent to itself, and not to some other object. In this case, “self” is the “Primus” class, since the method is inside the “Primus” class. Its declaration is in the Primus.h file and its implementation in the Primus.m file.
You may also notice that the method returns nothing "void". That is, a pun turns out: if there is no primus, then we create it, but it does not come out of the method. Why create it then? Suppose its functionality is implemented as follows:
id myPrimus; if (!self){ myPrimus = [self initWithGas:gas temperature:750]; } MasterPoRemonty *master = [myPrimus masterPoRemontuWithServiceItems:someItemsArray serviceSkills:someSkillsAray]; }
And here it is already clear that somewhere inside the method appears the repairman for the primus stove.
Why was the exclamation mark "!" Used? in brackets after “if”? In programming, this is a negation sign. That is, "! =" Sounds like "not equal." This method of condition is convenient for its conciseness. In this example, it was possible to use another condition in terms of structure that would carry the same function.
if (myPrimus == nil){}
This condition is 2 times as long and you need to fully read the entire line in order to understand it. This condition is small, but if you need to write something like this
if ((myPrimus == nil || yourPrimus == nil) && (mamaPrimus == nil || papaPrimus == nil)){}
then this structure
if ((!myPrimus || !yourPrimus) && (!mamaPrimus || !papaPrimus)){}
will be in a more advantageous position, both in terms of brevity and physical size. Previous construction - it may be trivial to simply not get into one line.
Consider how the implementation of this method would look like within the “Kitchen” class. In the file "Kitchen.m" the same method will be implemented like this:
-(void) doFireWithGas:(Gas *)gas { Primus *myPrimus; if (!myPrimus){ Primus *myPrimus = [Primus initWithGas:gas temperature:750]; } MasterPoRemonty *master = [myPrimus masterPoRemontuWithServiceItems:someItemsArray serviceSkills:someSkillsAray]; ... ... }
It can be seen that here you need to specify which object will be created, what its instance will be called and then send the method directly to the parent class.
That is, the cunning word "self" is used inside the class, as if you had already created an instance of it.
Primus *myPrimus;
and access the class instance. The only trick is that you didn’t create anything, and you’re not accessing the instance, but directly to the class. For clarity, I created an object
id myPrimus;
which can be accessed with the method. But it was possible not to create it, but to implement a more complex structure that would perform the same functions.
if (!self){ MasterPoRemonty *master = [[self initWithGas:gas temperature:750] masterPoRemontuWithServiceItems:someItemsArray serviceSkills:someSkillsAray]; }
In order to understand whether you can write “self” or not - just imagine what method you want to send to which object and start typing the word “self”, but not completely, for example “sel”. Xcode will offer several options, among which will be the actual “self”. To his left will be a description - what is the class. If this is the class to which you wanted to send the desired method (the class inside which you are performing the action), then use “self”. If Xcode indicates that “self” is not the object that you need, then use the name of the class or instance you need.
It also shows that the arguments were involved. Each argument has a type, which is also described in brackets, but after a colon. After the parentheses with the type of the argument comes the name of the argument. If there is a "*" in brackets after the argument type, then this is an object. If there is no "*" sign, then this is a scalar type, for example, "NSInteger", which is essentially a simple "int". Also “NSInteger” can be with a “*” sign for the passed argument. In this case, we will not change the variable itself, but the pointer to it. Topic Pointers is beyond the scope of this article. The name of the argument in this method.
-(void) doFireWithGas:(Gas *)gas;
will sound like "gas". Did you notice that the implementation did not use the normal name of the gas? For example, "Propan". The fact is that in the argument “gas” the right name of the gas is transmitted. From where We looked at how the method is implemented.
-(void) doFireWithGas:(Gas *)gas;
It involved a method
-(id) initWithGas:(Gas *)gas temperature:(NSInteger)t;
In this method there were 2 arguments “gas” and “t”. In the method's sending to the object, we indicated the temperature, and the type of gas was simply duplicated from the method
-(void) doFireWithGas:(Gas *)gas;
That is, this method is also sent somewhere. Let's take a closer look at the method.
(Primus *) hotAsHell;
Its implementation may look like this.
+(Primus *) hotAsHell{ self = [super init]; if (self){ [self doFireWithGas:propanButan]; } return self; }
Note the value of the argument being sent, "propanButan." It is transmitted throughout the class, from method to method.
It also shows that the method is sent to the object under certain conditions.
You need to know that none of your methods by themselves can work. He needs a "kick" outside. Pressing the button, the occurrence of any event or it should run the method of the protocol that the runtime environment starts at the right time. This hotAsHell method is sent only after an explicit call, it is not a system method, it must also be registered somewhere or assigned to something.
Now consider the method
-(id) initWithGas:(Gas *)gas temperature:(NSInteger)t;
It consists of the type of the returned object, the types of the arguments, the arguments and the selector. The selector is what remains of the method when it takes away from it the type of the returned object, the type of the arguments, and the arguments.
initWithGas:temperature:
precisely with colons. If there are no arguments, then there is no colon either, as is the case with “hotAsHell”. Often you will have to deal with the need to use a selector. Now you know what to use.
The concept of “super” was used a little higher.
What is “super”?
Consider the “hotAsHell” method implemented above. It has such a construction
self = [super init];
So it is customary to initialize the child class through the initialization of the parent.
Suppose that the Primus class is a direct descendant of the NSObject class. It is the class that stands on the hierarchy immediately above the class with which we work has the right to be called “super”. Team
[super init];
calls the init method of the NSObject instance. That is, an instance of the progenitor of all objects is automatically created - NSObject, with default (especially NSObject) parameters. Sending the init method NSObject returns self by NSObject. That is, an instance of NSObject itself. And this instance is assigned to our Primus object. After all, “self” in this case is precisely “Primus”. And at this stage we get an instance of the Primus object, which is no different from NSObject. Individual features it gives our sending method
[self doFireWithGas:propanButan];
as well as other methods implemented within this class.
Design
if (self) {...}
it's just a reinsurance in case something goes wrong and the default Primus is not created. those. parent class init method fails. In this case, usually do
... else {...}
where they are trying to rectify the situation, but, unfortunately, this is not the case and “else” will not help us.
And here I want to remind you about an uninitialized object from the beginning of the article. It is during the initialization of an instance of an object by its superclass that a place in memory is assigned to it and a pointer is sent to that place in memory. And when we check
if (self = [super init])
it is at this very moment that “self” can get an unexpected address in memory. That is, the received pointer will no longer be “self”. The superclass will not give us anything out of the ordinary. The object instance will be identical to the one we are going to work with. But the instance of this particular object will not be the instance that we need. This is such a rare mistake that you may not see it for a very long time in your applications. . , . . , , «alloc». «self»
if (self) {...}
. - .
,
return self;
«void», , . «Primus», «self» — «Primus». «Primus».
+(Kitchen *) kitchenFurniture:(NSArray *)furniture otherDishes:(NSArray *)dish; -(UkrainianBorsch *) borschWithIngredients:(NSarray)ingredients casserolAndPan:(NSArray)pan; -(MasterPoRemontu *) serviceItems:(NSArray *)i serviceSkills:(NSArray *)s;
— «Kitchen», «UkrainianBorsch» «MasterPoRemontu».
, «hotAsHell» , «Primus» .
?
- (id) initWithGas:(Gas *)gas temperature:(NSInteger)t { ... [self setGas:gas]; [self setTemperature:t]; ... }
,
Primus *myPrimus = [[Primus alloc] initWithGas:metan temperature:500];
[self setGas:metan]; [self setTemperature:500];
, *.h
«setGas» «setTemperature». , «variable», «set»:
setVariable
. , Primus.h «gas» «temperature». «set»
. :
@property (nonatomic, strong) Gas *gas; @property (nonatomic) NSInteger temperature;
@synthesize gas, temperature;
«setGas» «setTemperature». .
«Primus» ,
[myPrimus gas]; [myPrimus temperature];
or
myPrimus.gas; myPrimus.temperature;
NSLog(@" %@, %i", [myPrimus gas], myPrimus.temperature);
. , .
,
[myPrimus gas];
myPrimus.gas;
.
. , - «key-value coding».
myPrimus.gas;
[myPrimus valueForKey:@"gas"];
, «Primus» «gas».
[myPrimus setGas:metan];
«key-value coding»
[myPrimus setValue:@metan forKey:@"gas"];
«key-value coding» — . , , — .
, Objective-C . . , . , . «ivar», — .
runtime
, «runtime» «isa».
«runtime» « ». «runtime» C . , C .
[myPrimus initWithGas:gelium temperature:nil];
«runtime»
objc_msgSend(myPrimus,@selector(initWithGas:temperature:),gelium,nil);
Cocoa , : . , .
«isa».
, NSObject'. .
[super init];
NSobject, «isa», NSObject. , «runtime'», NSObject. , , NSObject'. «isa» , . , — NSArray UITableView CFDictionaryRef . «isa» NSArray UITableView CFDictionaryRef . , — «isa», , «runtime» .
- , , Objective-C.
, «singleton». -: « , „singleton“.
?
, , , . , , . , „initWithSomething:“ ? , , . , iPhone6 2 — - . , — . , „Bugatti Veyron“ „“.
„Primus“ .
+(Primus *) hotAsHell;
+(Primus*) hotAsHell{ static Primus *myPrimus = nil; static dispatch_once_t predicate; dispatch_once (&predicate, ^{myPrimus = [[super alloc] init];}); return myPrimus; }
. , „Primus“ .
, „Primus“, . , , , . : „ ?“. !
Primus *myPrimus = [[Primus alloc] initWitGas:metan temperature:500];
„Primus“,
Primus *myPrimus = [[Primus alloc] initWitGas:propan temperature:600];
„Primus“. .
, „hotAsHell“.
„static“, , . „nil“, . Design
static dispatch_once_t predicate;
() — »predicate" . , , .
dispatch_once (&predicate, ^{myPrimus = [[super alloc] init];});
. «dispatch_once» . «dispatch_once» . , , « „Primus“».
^{myPrimus = [[super alloc] init];}
. . -, myPrimus.
dispatch_once (&predicate, ^{myPrimus = [[super alloc] init];});
: «Primus» «myPrimus» - . «myPrimus» , . . GCD (Grand Central Dispatch). — .
return myPrimus;
— «Primus» , : — «Box», — «Etching», — «Performance». , . , , «Primus» . «Primus». «Primus» , . ,
Primus *myPrimus = [Primus hotAsHell];
«myPrimus» , .
Box *someBox = [Primus hotAsHell].Box;
«someBox» ,
[Primus hotAsHell].Box = someBox;
«Primus».
NSLog , . . . .
, . , , , MVC. Apple , .
. , , - , , . , 20 , . , , . , , . , . ? : « ?». — . , . -, , , .
[myPrimus doSomethingWith:Potato];
, , «Potato» -, «myPrimus». , . , , , .
. , . . , , . *.h
@interface Primus : UIViewController <UITableViewDataSource, UITableViewDelegate>
, «UITableViewDataSource» «UITableViewDelegate».
?
, , . : , , . . , . . , — , , . . , , -, . , , , /. Apple, . . , , < > . , - .
-(UIColor *) areaDidChangeColor:(CGRect)rect isActive:(BOOL)active;
«active» «YES». «rect»:
{ if (isActive && myForm == rect){ myColor = [UIColor redColor]; } return myColor; }
, , . For example:
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
«section» «tableView».
. , , , . , , - , , . - . , - — . , , .