Главная » iPhone, Objective-C, Программирование для iOS и MacOS » Слабые ссылки Objective-C

0

Как устранить  проблему  с циклическим  владением?  Используйте слабые  ссылки. Слабая ссылка представляет собой указатель, не подразумевающий владения. В нашей программе для разрыва циклического владения ресурс не должен быть владельцем своего держателя. Отредактируйте файл Asset.h, чтобы преобразовать держателя в слабую ссылку:

#import <Foundation/Foundation.h>

@class Employee;

@interface Asset : NSObject

{

NSString *label;

    weak Employee *holder; unsigned int resaleValue;

}

@property (strong) NSString *label;

@property (weak) Employee *holder;

@property unsigned int resaleValue;

@end

Постройте и запустите программу. Теперь все объекты уничтожаются так, как положено.

В отношениях «родитель/потомок» для предотвращения циклов владения обычно применяется простое правило: родитель является владельцем потомка, но потомок не должен быть владельцем родителя.

Обнуление слабых ссылок

Чтобы понаблюдать за работой слабых ссылок, давайте включим в нашу картину еще один массив. Допустим, нам понадобился массив всех ресурсов – даже тех, которые не были назначены ни одному конкретному работнику.

Ресурсы добавляются в массив по мере создания. Включите несколько строк кода в

main.m:

#import <Foundation/Foundation.h>

#import "Employee.h"

#import "Asset.h"

int main(int argc, const char * argv[])

{

@autoreleasepool {

// создание массива объектов Employee

NSMutableArray *employees = [[NSMutableArray alloc] init]; for (int i = 0; i < 10; i++) {

// создание экземпляра Employee

Employee *person = [[Employee alloc] init];

// присваивание значений переменным экземпляров [person setWeightInKilos:90 + i];

[person  setHeightInMeters:1.8  -­‐   i/10.0]; [person   setEmployeeID:i];

// включение работника в массив employees [employees addObject:person];

}

NSMutableArray *allAssets = [[NSMutableArray alloc] init];

// создание 10 экземпляров assets for (int i = 0; i < 10; i++) {

// создание экземпляра asset

Asset *asset = [[Asset alloc] init];

i];

// присваивание метки

NSString *currentLabel = [NSString stringWithFormat:@"Laptop %d",

[asset setLabel:currentLabel]; [asset setResaleValue:i * 17];

// получение случайного числа от 0 до 9 включительно NSUInteger randomIndex = random() % [employees count];

// получение соответсвующего работника

Employee *randomEmployee = [employees objectAtIndex:randomIndex];

// назначение ресурса работнику [randomEmployee addAssetsObject:asset];

[allAssets addObject:asset];

}

NSLog(@"Employees: %@", employees); NSLog(@"Giving up ownership of one employee"); [employees removeObjectAtIndex:5]; NSLog(@"allAssets: %@", allAssets); NSLog(@"Giving up ownership of arrays");

allAssets = nil;

employees = nil;

}

sleep(100); return 0;

}

Прежде чем строить и запускать программу, попробуйте предположить, как

будет выглядеть вывод. Вы увидите содержимое массива allAssets – после уничтожения экземпляра Employee №5. В каком состоянии будут находиться его ресурсы на этот момент? Они теряют одного владельца (экземпляр Employee

№5), но у них по-прежнему остается владелец allAssets, поэтому они не будут уничтожены.

Что происходит со значением holder для ресурсов, владельцем которых ранее

был экземпляр Employee №5? При уничтожении объекта, на который указывает слабая ссылка, переменная указателя обнуляется, то есть ей присваивается nil. Соответственно ресурсы экземпляра Employee №5 не будут уничтожены, а их переменной holder будут автоматически обнулены.

Теперь постройте и запустите про грамму и проверьте результат:

Employees: (

"<Employee 0: $0 in assets>",

"<Employee 9: $136 in assets>"

)

Giving up ownership of one employee deallocating <Employee 5: $136 in assets> allAssets: (

"<Laptop 0: $0, assigned to <Employee 3: $68 in assets>>", "<Laptop 1: $17, assigned to <Employee 6: $119 in assets>>", "<Laptop 2: $34, assigned to <Employee 7: $34 in assets>>", "<Laptop 3: $51 unassigned>",

"<Laptop 4: $68, assigned to <Employee 3: $68 in assets>>",

"<Laptop 5: $85 unassigned>",

"<Laptop 6: $102, assigned to <Employee 6: $119 in assets>>", "<Laptop 7: $119, assigned to <Employee 2: $119 in assets>>", "<Laptop 8: $136, assigned to <Employee 9: $136 in assets>>", "<Laptop 9: $153, assigned to <Employee 1: $153 in assets>>"

)

Giving up ownership of arrays deallocing <Laptop 3: $51 unassigned>

deallocing <Laptop 8: $136 unassigned>

Источник: Аарон Хилегас, «Objective-C. Программирование для iOS и MacOS», 2012 г.

По теме:

  • Комментарии