lecture 06. ios programming. Основи objective-c

Post on 12-Apr-2017

53 Views

Category:

Software

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Lecture 06. iOS Programming. Основи Objective-CLviv Polytechnic National University

Davydov M.V.

iOS є UNIX-подібною операційною системою. Ядро платформи – Darwin. Фактично розроблена на основі Mac OS X.

В свою чергу, ядро Darwin базується на BSD та NextStep.

Розмір операційної системи на мобільному пристрої складає близько 2 ГБ.

Основними елементами платформи є: Cocoa Touch Layer, Media Layer,

Core Services та Core OS

Cocoa Touch – найвищий рівень API.

В свою чергу складається з наборів бібліотек: Cocoa Touch Frameworks,

Address Book UI, Event Kit UI, Game Kit,

iAd, MapKit,

Message UI, UI Kit та ін.

Фактично Cocoa Touch Layer – це спрощення настільної версії Cocoa з доданими функціями

розпізнавання жестів, анімації та технології multi-touch.

Media Layer складається з: Asset Library, AVFoundation,

Core Audio, Core Graphics,

Core MIDI, Core Text,

Core Video, Image IO,

Media Player, Open AL,

OpenGL ES, Quartz Core та інших.

Core Services Layer складається з:

Address Book,

CFNetwork, Core Data,

Core Foundation, Core Location, Core Media,

Core Telephony, Event Kit,

Foundation, Store Kit та інших.

Функції рівня Core OS базуються на стандарті POSIX.

POSIX-standard (Portable Operating System Interface for Unix) – це набір стандартів, які описують інтерфейси між операційною системою та прикладною програмою, бібліотеку мови C.

Стандарт створений для забезпечення сумісності різних UNIX-подібних операційних систем та

портованості прикладних програм на рівні вихідного коду прикладних програм.

Основним засобом розробки на мобільній платформі iOS є XCode. Інтерфейс середовища розробки XCode є доволі незвичним, проте містить всі необхідні засоби для розробки включаючи засоби перевірки синтаксису,

розробки інтерфейсу, компілятори та відлагоджувачі.

Основними файлами проекту в XCode є: .h - “header” (or interface file) – файл заголовків

.m - “message” (or implementation file) – файл з реалізацією (Objective C)

.mm - “message” (or implementation file) – файл з реалізацією (Objective C++)

.swift - вихідні файли на мові програмування Swift .xib – (XML interface builder file) – файл ресурсів

До набору інструментів XCode входить емулятор мобільних пристроїв iPhone та

iPad.

Програмування для платформи iOS передбачає наслідування двох ключових парадигм – об’єктно-

орієнтованого програмування та шаблону проектування MVC.

MVC на iOS здійснюється на основі: View - вид забезпечується класами UIView та

UIViewController Controller - поведінка контролера здійснюється через три ключові технології – делегування, повідомлення

та target-action.

Класи UIView та UIVIewController відповідають за розміщення елементів управління.

Види є ієрархічними та будуються як дерево з під-видами.

Вид може бути або головним або в складі іншого виду, доданим за допомогою методу addSubview.

UIViewController не є компонентом Controller в MVC. Він реалізує лише додаткову функціональність для

навігації.

Згідно з концепцією Target-action, програма розділена на об’єкти, які динамічно встановлюють зв’язок один з

одним на основі повідомлень.

The term target–action design paradigm refers to a kind of software architecture, where a computer program is

divided into objects which dynamically establish relationships by telling each other which object they

should target and what action or message to send to that target when an event occurs.

This is especially useful when implementing graphical user interfaces, which are by nature event-driven.

[button setTarget: self]; [button setAction: @selector(doSomething)];

[button setTarget: self]; [button setAction: NSSelectorFromString([textField stringValue])];

Важливо - ":" є частиною назви методу

Це різні селектори @selector(doSomething) @selector(doSomething:)

Перший вказує на метод без параметрів другий - з параметрами

This is possible because, under Objective-C, methods are represented by a selector, a simple

string describing the method to be called.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(useNotificationWindowDidLoad:) name:@"WindowDidLoad" object:nil];

-(void)useNotificationWindowDidLoad:(NSNotification *) notification { …

}

When a message is sent, the selector is sent into the ObjC runtime, matched against a list of available methods, and the method's implementation is called. The implementation of the method is looked up at runtime, not compile time.

Objective-C Language⦿ Objective-C is an object oriented language. ⦿ follows ANSI C style coding with methods

from Smalltalk

⦿ Flexible almost everything is done at runtime. ● Dynamic Binding ● Dynamic Typing ● Dynamic Linking

Apple and Mac OS X⦿ NeXT is taken over by Apple in 1996 and

put Steve Jobs and his Objective-C libraries to work

⦿ Redesigned Mac OS to use objective-C similar to that of NeXTSTEP

⦿ Developed a collection of libraries named “Cocoa” to aid GUI development

⦿ Release Mac OS X (ten), which was radically different than OS 9, in March 2001

The Cocoa API⦿ Developed by Apple from NeXTSTEP and

OPENSTEP

⦿ Has a set of predefined classes and types such as NSnumber, NSstring, Nsdate, etc.

⦿ NS stands for NeXT-STEP ⦿ Includes a root class NSObject where words like

alloc, retain, and release come from

Dynamic Language⦿ Almost everything is done at runtime

⦿ Uses dynamic typing, linking, and binding

⦿ This allows for greater flexibility

⦿ Minimizes RAM and CPU usage

To Import or Include?⦿ C/C++’s #include will insert head.h into

the code even if its been added before.

⦿ Obj-C’s #import checks if head.h has been imported beforehand.

#import “head.h”

Inherited from C⦿ all basic types ⦿ functions (non-members) ⦿ pointers ⦿ operators ⦿ all main instructions (cycles, conditions) ⦿ global and static variables

New in Objective C⦿ for … in … loop ⦿ Introduced in Objective-C 2.0 (“fast

enumeration”)

for(Item_Type *item in Collection_of_Items) {

//do whatever with the item Nslog(@” Looking now at %@”, item); }

Note: %@ in the NSLogconverts whatever is passed (in this case item) to a string

Main Funciton – подібно до мови C

#import <someheaders.h>

int main(int argc, const char *argv[]) { @autoreleasepool { //your code here******* // об’єкти, додані в autorelease пул з використанням // виклику autorelease або методів, які вертають тимчасові

// об’єкти будуть автоматично знищені

return 0; }

}

Вивід тексту - printf, NSLog⦿ Two standard functions you see used

⦿ printf() – same as C ○ printf(“Hi Lynne”); //this is actual C code

⦿ NSLog() ○ NSLog(@”Hi Lynne”); //this is strictly Objective-

C

Класи (об’єкти) — не класи C++!!!

⦿ Have both definition file and implementation file : classname.h and classname.m

⦿ Similar to how have .h and .cpp in C++

Означення класу (інтерфейс)#import <Cocoa/Cocoa.h>…@interface <Назва класу> : <Батьківський клас>{

// відкриті поля }// методи і атрибути@end

Приклад інтерфейсу (класу)#import <Cocoa/Cocoa.h>@interface Node : NSObject {

Node *link;int contents;

}+(id)new; //static(class) member-(void)setContent:(int)number;-(void)setLink:(Node*)next;-(int)getContent;-(Node*)getLink;@end

Node.h

Реалізація інтерфейсу

#import "interface_file.h"

@implementation <назва класу>// приватні поля класу// реалізація відкритих і // приватних методів@end

Приклад реалізації (класу)#import “Node.h”@implementation Node+(id)new { return [Node alloc];}-(void)setContent:(int)number {contents = number;}-(void)setLink:(Node*)next{

[link autorelease];link = [next retain];

}-(int)getContent { return contents; }-(Node*)getLink { return link; }@end

Node.m

Приклад інтерфейсу (класу)@interface AppDelegate : NSObject <NSApplicationDelegate>

@property (retain) WindowController *myWindowController; @property (weak) IBOutlet DesktopUIMenu *desktopMenu; @property (nonatomic, retain) NSURL* inputImageURL;

@end

AppDelegate.h

Приклад реалізації (класу)@interface AppDelegate () {

// приватні поля NSOutputStream *_outputStream; NSInputStream *_inputStream; } @end

@implementation AppDelegate { // приватні поля NSURL* _inputImageURL; }

@synthesize NSURL* inputImageURL = _inputImageURL; // методи - (void)applicationWillTerminate:(NSNotification *)aNotification{ // Insert code here to tear down your application [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"isOpenGLIsLoaded"]; }

@end

AppDelegate.m

Оголошення методів

C++ syntax

Objective-C syntax

void function(int x, int y, char z);

Object.function(x, y, z);

-(void) method:(int)x, (int)y, (char)z;

[Object function:x, y, z];

- (void)driveCar:(Car *)car withPerson:(Person *)person;[carController driveCar:car withPerson:person];

+ і – в оголошенні методу⦿ Оголошення методу в інтерфейсі починається з «+» або «-»

⦿ + означає, що це — “метод класу (типу)” який викликання через посилання на тип (як статичні методи в Java)

⦿ - означає, що це — “метод об’єкту”, який викликається через посилання на об’єкт (як звичайні методи у Java)

Створення екземплярів об’єктівClassName *object = [[ClassName alloc] init]; ClassName *object = [[ClassName alloc] initWith* ];

● NSString* myString = [[NSString alloc] init]; ● Nested method call. The first is the alloc method called on NSString itself. This is

a relatively low-level call which reserves memory and instantiates an object. The second is a call to init on the new object. The init implementation usually does basic setup, such as creating instance variables. The details of that are unknown to you as a client of the class. In some cases, you may use a different version of init which takes input:

ClassName *object = [ClassName method_to_create];● NSString* myString = [NSString string]; ● Some classes may define a special method that will in essence call alloc followed by some kind of

init

Creating an Object

Виклик методу — це надсилання повідомлення⦿ Almost every object manipulation is done by

sending objects a message ⦿ Two words within a set of brackets, the object

identifier and the message to send.

Like C++ or Java’s Identifier.message()

[Identifier message ]

Доступ до полів класу — лише через методи або властивості

[object setXXXMethod:value1];

[object setXXXMethod:value1 with:secondArgument];

C++ VS. Objective-C⦿ Adds OOP,

metaprogramming and generic programming to C

⦿ Comes with a std library

⦿ Has numerous uses ⦿ Large and complex

code for OOP

⦿ Only adds OOP to C ⦿ Has no standard

library; is dependant on other libraries

⦿ Mostly used for application building

⦿ Simpler way of handling classes and objects

Keyword: id⦿ The word ‘id’ indicates an identifier for an

object much like a pointer in c++ ⦿ This uses dynamic typing ⦿ For example, if Pen is a class…

extern id Pen;

id myPen;

myPen = [Pen new ];

id work like pointers to objects.

Memory Allocation⦿ Objects are created dynamically through

the keyword, “alloc” ⦿ Objects are automatically deallocated in

latest Objective-C through automatic reference counting

NSInteger and NSUintegerNSInteger number; (Like long in C) NSUIntneger another; (Like unsigned long in C)

● Objective-C data types that are 32-Bits on 32-Bit platforms and 64-bits on 64-bit platforms

NSStringNSString *theMessage = @”hello world”;

● Number of characters in a string ○ NSUInteger charCount = [theMessage length];

● Test if 2 strings equal ○ if([string_var_1 isEqual: string_var_2])

{ //code for equal case }

String literal in Objective-C⦿ Begins with the @ symbol ⦿ @”Lynne Grewe”;

Some Examples NSString *myString = @”Hello World”;

int len = [myString length];

OR int len = [@”Hello World” length];

OR NSString *myString = [[NSString alloc] initWithString:@”Hello World”]; int len = [myString length];

Formatting Strings in output NSLog

int a = 1; float b = 33.22; char c = ‘A’; NSLog(@”Integer %d Float: %f Char: %c”, a, b, c);

NSString ---not changeable⦿ International (any language) strings using Unicode. ⦿ Compiler will create an NSString for you using

@“foo” notation. ⦿ An NSString instance can not be modified! They

are immutable. ⦿ Usual usage pattern is to send a message to an

NSString and it will return you a new one. ● self.display.text = [self.display.text stringByAppendingString:digit]; ● self.display.text = [NSString stringWithFormat:@“%g”, brain.operand]; // class

method

⦿ Tons of utility functions available (case conversion, URLs, substrings, type conversions, etc.).

NSMutableString ---changeable⦿ Mutable version of NSString. Somewhat rarely

used.

⦿ Can do some of the things NSString can do without creating a new one (i.e. in-place changes).

NSMutableString *ms = [[NSMutableString alloc] initWithString:@“0.”]; NSMutableString *ms = [NSMutableString stringWithString:@“0.”]; // inherited from

NSString [ms appendString:digit];

NSNumber⦿ Object wrapper around primitive types

like int, float, double, BOOL, etc. NSNumber *num = [NSNumber numberWithInt:36]; float f = [num floatValue]; // would return 36 as a float (i.e. will convert types)

⦿ Useful when you want to put multiple numeric primitive types in a collection (e.g. NSArray or NSDictionary).

NSValue⦿ Generic object wrapper for other non-

object data types. CGPoint point = CGPointMake(25.0, 15.0); // CGPoint is a C

struct NSValue *pointObject = [NSValue valueWithCGPoint:point];

NSData⦿ “Bag of bits.” Used to save/restore/

transmit data throughout the iOS SDK.

NSDate⦿ “Used to find out the time right now or to

store past or future times/dates. ⦿ See also NSCalendar, NSDateFormatter,

NSDateComponents.

NSArray – holds fixed array of points to objectsNSArray *thearray = [NSArray arrayWithObjects:o1,o2,o3,o4,

nil];

//get element [thearray objectAtIndex:0]; //element at index 0

Example

NSDate *now = [NSDate date]; NSDate *tomorrow = [now dateByAddingTImeInterval:24.0*60.0*60.0]; //add a day NSDate *yesterday = [now dateByAddingTimeInterval:-24.0*60.0*60.0]; //minus a

day

//array of Dates NSArray *dateList = [NSArray arrayWithObjects:now, tomorrow, yesterday];

//get elements in array NSDate *first = [dateList objectAtIndex:0];

Methods are: count = gets number of items in arrayobjectAtIndex:i = returns element i of array (starting from 0)

Note: you can not add or remove a pointer from an NSArray---fixed once created

NSArray – cycle through with for loop

NSDate *now = [NSDate date]; NSDate *tomorrow = [now dateByAddingTImeInterval:24.0*60.0*60.0]; //add a day NSDate *yesterday = [now dateByAddingTimeInterval:-24.0*60.0*60.0]; //minus a day

//array of Dates NSArray *dateList = [NSArray arrayWithObjects:now, tomorrow, yesterday];

//get elements in array NSDate *first = [dateList objectAtIndex:0];

NSUInteger dateCount = [dateList count]; for(int i=0; i<dateCount; i++) { NSDAte *d = [dateList objectAtIndex:i]; NSLog(@” Date is %@”, d); }

Methods are: count = gets number of items in arrayobjectAtIndex:i = returns element i of array (starting from 0)

NSArray – cycle through with for loop OPTION 2

NSDate *now = [NSDate date]; NSDate *tomorrow = [now dateByAddingTImeInterval:24.0*60.0*60.0]; //add a day NSDate *yesterday = [now dateByAddingTimeInterval:-24.0*60.0*60.0]; //minus a day

//array of Dates NSArray *dateList = [NSArray arrayWithObjects:now, tomorrow, yesterday];

//get elements in array NSDate *first = [dateList objectAtIndex:0];

For(NSDate *d in dateList) { NSLog(@” Date is %@”, d); }

This is a “for in” loop --- convinient

NSMutableArray – changeable array of pointers to objects.NSMutableArray *thearray = [NSArray arrayWithObjects:o1,o2,o3,o4,

nil];

//get element [thearray objectAtIndex:0]; //element at index 0

Example NSDate *now = [NSDate date]; NSDate *tomorrow = [now dateByAddingTImeInterval:24.0*60.0*60.0]; //add a day NSDate *yesterday = [now dateByAddingTimeInterval:-24.0*60.0*60.0]; //minus a day

//array of Dates NSMutableArray *dateList = [NSMutableArray array];

//set elements [dateList addObject:now]; [dateList addObject:tomorrow]; [dateList addObject:yesterday];

Methods are: array = gets empty NSMutableArrayaddObject:obj = adds as next element the obj to array

Note: you can add or remove a pointer from an NSMutableArray

NSDictionary⦿ Immutable hash table. Look up objects using

a key to get a value. + (id)dictionaryWithObjects:(NSArray *)values forKeys:(NSArray *)keys; + (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...;

⦿ Creation example: NSDictionary *base = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:2], @“binary”, [NSNumber numberWithInt:16], @“hexadecimal”, nil];

⦿ Methods ● - (int)count; ● - (id)objectForKey:(id)key; ● - (NSArray *)allKeys; ● - (NSArray *)allValues;

see documentation (apple.com) for more details

NSMutableDictionary⦿ Changeable + (id)dictionaryWithObjects:(NSArray *)values forKeys:(NSArray *)keys; + (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...;

⦿ Creation : + (id)dictionary; //creates empty dictionary

⦿ Methods - (void)setObject:(id)anObject forKey:(id)key; - (void)removeObjectForKey:(id)key; - (void)removeAllObjects; - (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;

see documentation (apple.com) for more details

Other useful Objective-C data classes⦿ NSSet, NSMutableSet, NSOrderedSet,

NSMutableOrderedSet

Objective-C

Memory management Memory management is semi-automatic:

The programmer must allocate memory for objects either a) explicitly (alloc) or b) indirectly using a convenience constructor

No need to de-allocate

Objective-C memory management1) Old mode - MRC (Manual Reference Counting) 2) New mode - ARC (Automatic Reference Counting) These modes could not be mixed!!!

Automatic Reference Counting⦿ Objective C uses ‘AUTOMATIC reference

counting' as default memory management

⦿ keeps an internal count of how many times an Object is 'needed'.

⦿ System makes sure that objects that are needed are not deleted, and when an object is not needed it is deleted.

AllocationAllocation happens through the class method alloc.

The message ‘alloc’ is sent to the class of the requested object. Alloc is inherited from NSObject. Every alloc creates a new instance (=object)

[HelloWorld alloc]; The class creates the object with all zeros in it and

returns a pointer to it. HelloWorld *p = [HelloWorld alloc]; The pointer p now points to the new instance. Now we send messages to the instance through p.

The reference counter• Every instance has a reference counter. It

counts how many references are retaining the object. The counter is 1 after allocation. It does not count how many references exist to the object

• Sending the retain message to the object increases the reference counter by 1.

• Sending the release message decreases the reference counter by 1.

• No need to do either if using ARC.

reference counter = retain counter

• When the reference counter reaches zero, the object is automatically de-allocated. The programmer does not de-allocate.

• The programmer only does: alloc retain release

Rules for memory management

• With no ARC: The method that does an alloc or a retain must also do a release, it must maintain the balance between:

(alloc or retain) and (release)

• If a method does alloc and returns a pointer to the created object then the method must do an autorelease instead of release.

Autorelease pool without ARC• With no ARC: For autorelease to work the

programmer must create an autorelease pool, using:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

• When Cocoa is used then the autorelease pool is created automatically – the programmer does not need to do it.

• To release the pool and all objects in it, do: [pool release];

Autorelease pool new syntax (works with and without ARC)

@autoreleasepool{ // Code that creates // autoreleased objects.}

Convenience Constructors• This is a class method that allocates and

initializes an object. The programmer is neither doing alloc nor init.

• Example:

+(id)studentWithName :(NSString*)name AndGpa:(float)gpa { id newInst = [[self alloc]initStudent:name :gpa]; return [newInst autorelease]; }

Convenience Constructors

• Essential: the method sends alloc to self which is the Student class object

• Essential: the method autoreleases the instance, because it returns a pointer to the created instance

• Not essential: This example uses an existing initializer, it could use something else or initialize the Student data directly

Convenience Constructors

Calling the convenience constructor: id stud = [Student studentWithName:@"Johnnie" AndGpa: 3.8];

The message is sent to the Student class object and returns a pointer to it, the pointer is assigned to stud

The calling code does neither alloc nor init An autorelease pool must be in place

Код, який працює з ARC і без ARC

NSString *nsstring = [[NSString alloc] initWithFormat:format_message arguments:valist];

… #if !__has_feature(objc_arc) [nsstring release]; #endif

ARC не працює в структурах і класах С/C++

struct Data { NSMutableArray *array; };

error: ARC forbids Objective-C objs in structs or unions NSMutableArray *array;

Але можна зберігати вказівник без підрахунку посилань

struct Data

{

NSMutableArray __unsafe_unretained *array;

};

As described previously, the compiler doesn’t manage variables with the __unsafe_unretained ownership qualifier. You have to take care of ownership yourself to avoid a memory leak or the application will crash.

Bridging

Object Type Variables Cannot Be Members of struct or union in C Language When you add a member variable of Objective-C object type to C struct or union, a compile error occurs. struct Data

{

NSMutableArray *array;

};

error: ARC forbids Objective-C objs in structs or unions NSMutableArray *array;

__bridge cast

You can use __bridge cast as id obj = [[NSObject alloc] init];

void *p = (__bridge void *)obj;

id o = (__bridge id)p;

Dangerous! P does not have ownership!!!

__bridge_retained castПриведення типу зі збільшенням кількості посилань:id obj = [[NSObject alloc] init]; void *p = (__bridge_retained void *)obj;

The above source code can be rewritten for a non-ARC environment as follows. /* non-ARC */ id obj = [[NSObject alloc] init];

void *p = obj; [(id)p retain];

Суміщення Objective-C і Swift

• З Objective-C можна викликати код на C, C++, відправляти повідомлення об’єктам Swift

• Зі Swift можна відправляти відправляти повідомлення об’єктам Objective-C

Bridging header - має імпотувати всі Objective-C класи, які будуть використовуватися зі Swift

Test-Bridging-Header.h#ifndef Test_Bridging_Header_h #define Test_Bridging_Header_h

#import "Test.h"

#endif /* Test_Bridging_Header_h */

Calling Objective-C from Swift

#import "Test.h"

@implementation Test

- (void) someMethod: (int) a { NSLog(@"SomeMethod with a=%d", a); }

@end

Test.m

Test.h#import <Foundation/Foundation.h>

@interface Test : NSObject

@property (strong, nonatomic) id someProperty;

- (void) someMethod : (int)a;

@end

Використання Objective-C класу зі Swift

let t = Test(); t.someMethod(24);

Виклик Swift коду з Objective-C

class SomeSwiftClass : NSObject { func showLog(x: Test) { print("Hello Swift ", x.getInt()) } }

1. Створити Swift клас

Виклик Swift коду з Objective-C

#import "Test.h" // import swift declarations "<ProjectName>-Swift.h" #import "Test1-Swift.h"

@implementation Test

- (void) someMethod: (int) a { NSLog(@"SomeMethod Ran %d", a); SomeSwiftClass * c = [[SomeSwiftClass alloc] init]; [c showLogWithX:self]; }

-(int)getInt { return 24; }

@end

2. Імпортувати файл заголовків зі Swift

ЗауваженняНазви методів змінюються з використанням правил іменування Objective-C:

Swift:class SomeSwiftClass : NSObject { func showLog(x: Test, a: Int) { print("Hello Swift ", x.getInt(), " ", a) } } Згенерований Objective-C заголовок:

SWIFT_CLASS("_TtC5Test114SomeSwiftClass") @interface SomeSwiftClass : NSObject - (void)showLogWithX:(Test * _Nonnull)x a:(NSInteger)a; - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; @end

Згенеровані назви методів можна взнати, якщо перейти на означення класу SomeSwiftClass з Objective-C

Рекомендована література

top related