@classCzęść NR.5W C# przestrzenie nazw spełniają dwa cele:

1. Unikanie kolizji z klasami o podobnej nazwie.

2.Poinformowanie danej klasy, że obiekt jest dostępny.

Jak sprawa wygląda w Objective-C.

using System;
using System.Collections.Generic;
using CezaryCompany.Classes
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "CustomClass.h"

Jak widzisz w Objective-C nie ma czegoś takiego jak przestrzenie nazw. Wszystko bazuje na plikach. Informujesz więc każdą klasę o tym jakie interfejsy (.h) są zdefiniowane w innych plikach nagłówkowych (headers).

Wyrażenie “import” definiuje plik nagłówkowy, który jest w projekcie. Inne “importy” są zdefiniowane w innych frameworkach (odpowiednik dll-ek). Jak widać na powyższym przykładzie <Foundation/Foundation.h> jest odwołaniem do frameworku.

Deklarując frameworku deklarujesz użycie wszystkich jego nagłówków.

Koncepcja wydaje się prosta ale istnieje pewien problem. Co się stanie jeśli oba obiekty potrzebują wzajemnie swoich referencji.

Oto przykład dwóch interfejsów, które wzajemnie siebie potrzebują.

#import <Foundation/Foundation.h>
#import "MyOtherObject.h"

@interface MyObject : NSObject

@property(nonatomic,retain)MyOtherObject* obj;

@end

 

#import <Foundation/Foundation.h>
#import "MyObject.h"

@interface MyOtherObject : NSObject

-(void) DoSomething;

@property(nonatomic,retain)MyObject* obj;

@end

W rezultacie kompilator zgłupieje i stwierdzi, że oba nagłówki nie istnieją czyli nie możemy stworzyć właściwości klasy MyObject i MyOtherObject.

W takim wypadku musimy użyć wrażenia “@class”.

#import <Foundation/Foundation.h>
@class MyOtherObject;

@interface MyObject : NSObject

@property(nonatomic,retain)MyOtherObject* obj;

@end

W tym wypadku mówimy kompilatorowi, że obiekt “MyOtherObject” będzie istniał w pewnym momencie (ale nie teraz) więc poudawaj na razie, że on jest.

Wciąż jednak możemy otrzymać błąd kompilacji ponieważ obiekt “MyOtherObject” nie istnieje na poziomie plików implementacyjnych. Co więc robimy? Dodajemy wyrażenie “import” w pliku implementacyjnym.

#import "MyObject.h"
#import "MyOtherObject.h"

@implementation MyObject
-(id)init
{
    self = [super self];
    
    if (self)
    {
        self.obj = [[MyOtherObject alloc]init];
    }
    return self;
}


@end

Oto rozwiązanie naszego problemu.

Importy nie są tak intuicyjne jak przestrzenie nazw ale tak naprawdę trzeba tylko zrozumieć jak kompilator Objective-C działa.

Kolizję

Kolizji trzeba unikać więc nazywam swoje klasy z głową.

Jeżeli jednak taki przypadek się zdarzy wystarczy użyć następujące dyrektywy.

@compatibility_alias NewClassName OriginalClassName;

Ta dyrektywa zmieni nazwę klasy likwidując w ten sposób problem kolizji nazw.