Ios 属性、线程、内存管理和Rock&;滚
环境:Mac OS X 10.9,Xcode 5.0.2,ARC禁用 问题:如何在所有线程完成作业后释放属性内存。见下面的例子 我正在用一个按钮创建一个小示例“(iAction)btnRun:(id)sender”。 示例读取txt文件并填充NSArray属性(sharedListWords)。然后运行两个线程,每个线程显示单词,Ios 属性、线程、内存管理和Rock&;滚,ios,objective-c,multithreading,memory-management,Ios,Objective C,Multithreading,Memory Management,环境:Mac OS X 10.9,Xcode 5.0.2,ARC禁用 问题:如何在所有线程完成作业后释放属性内存。见下面的例子 我正在用一个按钮创建一个小示例“(iAction)btnRun:(id)sender”。 示例读取txt文件并填充NSArray属性(sharedListWords)。然后运行两个线程,每个线程显示单词,请参见第节。当线程完成作业时,属性(self.sharedListWords)不会被释放!但我需要为(self.sharedListWords)属性分配的可用内存。操作
请参见第节。当线程完成作业时,属性(self.sharedListWords)不会被释放!但我需要为(self.sharedListWords)属性分配的可用内存。操作“btnRun”在线程完成作业之前退出,在此操作中我无法释放(self.sharedListWords) 线程完成作业后如何释放属性(self.sharedListWords)的内存?通过创建依赖项操作jobFinished(),回答是很好,但如何正确释放属性? 这是我在Objective-c上的第一个多线程程序,我将很高兴进行调整
AppDelegate.h:
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
{
volatile int32_t sharedIndex; // Shared between threads, current index in array
NSOperationQueue* operationQueue;
}
@property (assign) IBOutlet NSWindow *window;
// Shared between threads, list of words
@property (atomic, retain) NSArray* sharedListWords;
- (void)worker;
@end
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
{
volatile int32_t sharedIndex; // Shared between threads, current index in array
NSOperationQueue* operationQueue;
}
@property (assign) IBOutlet NSWindow *window;
// Shared between threads, list of words
@property (atomic, retain) NSArray* sharedListWords;
- (void)worker;
@end
#导入
@接口AppDelegate:NSObject
{
volatile int32_t sharedIndex;//线程之间共享,数组中的当前索引
NSOperationQueue*操作队列;
}
@属性(分配)窗口*窗口;
//线程间共享,单词列表
@属性(原子,保留)NSArray*sharedListWords;
-(b)工人;
@结束
AppDelegate.m:
#import "AppDelegate.h"
@implementation AppDelegate
- (IBAction)btnRun:(id)sender
{
// Read txt file dictionary of words, where is each words in new line.
NSString* dictionaryFilePath = [NSString stringWithFormat:@"/Users/admin/dictionary.txt"];
NSString* fileContents = [NSString stringWithContentsOfFile:dictionaryFilePath
encoding:NSUTF8StringEncoding error:nil];
// Get array of string separated by new line
self.sharedListWords = [fileContents componentsSeparatedByCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
//self.sharedListWords = @[@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eight",@"nine",@"ten"];
self->sharedIndex = -1;
int numberOfThreads = 2;
// Run method working() in separate threads
for(int i=0; i<numberOfThreads; ++i)
{
//////////////////////////////////////////
// Create a thread
// Create new NSOperatin object with function puting in @selector() for run in other thread.
NSOperation* startBruteOper = [[NSInvocationOperation alloc]
initWithTarget:self selector:@selector(worker) object:nil];
// Add the operation to the queue and let it to be executed.
[operationQueue addOperation:startBruteOper];
[startBruteOper release];
/////////////////////////////////////////
}
}
- (void)worker
{
unsigned long countWords = [self.sharedListWords count];
int32_t index = 0;
// Use atomic operation for thread safe
while( (index = OSAtomicIncrement32( &(self->sharedIndex) ) ) < countWords )
{
NSLog(@"[%@] working on \"%@\"",
[NSThread currentThread],
[self.sharedListWords objectAtIndex:index]);
}
NSLog(@"[%@] work is finish.", [NSThread currentThread]);
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Multithreading queue list
operationQueue = [[NSOperationQueue alloc] init];
}
@end
#import "AppDelegate.h"
@implementation AppDelegate
- (IBAction)btnRun:(id)sender
{
// Read txt file dictionary of words, where is each words in new line.
NSString* dictionaryFilePath = [NSString stringWithFormat:@"/Users/admin/dictionary.txt"];
NSString* fileContents = [NSString stringWithContentsOfFile:dictionaryFilePath
encoding:NSUTF8StringEncoding error:nil];
// Get array of string separated by new line
self.sharedListWords = [fileContents componentsSeparatedByCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
//self.sharedListWords = @[@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eight",@"nine",@"ten"];
self->sharedIndex = -1;
int numberOfThreads = 2;
NSOperation* jobFinishedOper = [[NSInvocationOperation alloc]
initWithTarget:self selector:@selector(jobFinished) object:nil];
// Run method working() in separate threads
for(int i=0; i<numberOfThreads; ++i)
{
//////////////////////////////////////////
// Create a thread
// Create new NSOperatin object with function puting in @selector() for run in other thread.
NSOperation* startBruteOper = [[NSInvocationOperation alloc]
initWithTarget:self selector:@selector(worker) object:nil];
// Add the operation to the queue and let it to be executed.
[operationQueue addOperation:startBruteOper];
[jobFinishedOper addDependency:startBruteOper]; // 'jobFinishedOper' run only when 'startBruteOper' finished!
[startBruteOper release];
/////////////////////////////////////////
}
// 'jobFinishedOper' run only when all prevous operation is finished!
[operationQueue addOperation:jobFinishedOper];
[jobFinishedOper release];
}
- (void)worker
{
unsigned long countWords = [self.sharedListWords count];
int32_t index = 0;
// Use atomic operation for thread safe
while( (index = OSAtomicIncrement32( &(self->sharedIndex) ) ) < countWords )
{
NSLog(@"[%@] working on \"%@\"",
[NSThread currentThread],
[self.sharedListWords objectAtIndex:index]);
}
NSLog(@"[%@] work is finish.", [NSThread currentThread]);
}
- (void)jobFinished
{
self.sharedListWords = nil;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Multithreading queue list
operationQueue = [[NSOperationQueue alloc] init];
}
@end
#导入“AppDelegate.h”
@实现AppDelegate
-(iAction)btnRun:(id)发送方
{
//阅读txt文件字典中的单词,其中每一个单词都在新行中。
NSString*dictionaryFilePath=[NSString stringWithFormat:@”/Users/admin/dictionary.txt];
NSString*fileContents=[NSString stringWithContentsOfFile:dictionaryFilePath
编码:NSUTF8StringEncoding错误:nil];
//获取由新行分隔的字符串数组
self.sharedListWords=[fileContents组件由字符分隔集:
[NSCharacterSet newlineCharacterSet]];
//self.sharedListWords=@[“一”,“二”,“三”,“四”,“五”,“六”,“七”,“八”,“九”,“十];
self->sharedIndex=-1;
int numberOfThreads=2;
//在单独的线程中运行方法working()
对于(int i=0;isharedIndex))
外段:
[您可以添加另一个依赖于所有“辅助”操作的操作,如下所示:
描述于
该操作在其所有依赖项完成后运行,因此您可以调用
self.sharedListWords = nil;
在完成的操作中释放数组。这是正确的代码,遵循Martins指令
AppDelegate.h:
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
{
volatile int32_t sharedIndex; // Shared between threads, current index in array
NSOperationQueue* operationQueue;
}
@property (assign) IBOutlet NSWindow *window;
// Shared between threads, list of words
@property (atomic, retain) NSArray* sharedListWords;
- (void)worker;
@end
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
{
volatile int32_t sharedIndex; // Shared between threads, current index in array
NSOperationQueue* operationQueue;
}
@property (assign) IBOutlet NSWindow *window;
// Shared between threads, list of words
@property (atomic, retain) NSArray* sharedListWords;
- (void)worker;
@end
#导入
@接口AppDelegate:NSObject
{
volatile int32_t sharedIndex;//线程之间共享,数组中的当前索引
NSOperationQueue*操作队列;
}
@属性(分配)窗口*窗口;
//线程间共享,单词列表
@属性(原子,保留)NSArray*sharedListWords;
-(b)工人;
@结束
AppDelegate.m:
#import "AppDelegate.h"
@implementation AppDelegate
- (IBAction)btnRun:(id)sender
{
// Read txt file dictionary of words, where is each words in new line.
NSString* dictionaryFilePath = [NSString stringWithFormat:@"/Users/admin/dictionary.txt"];
NSString* fileContents = [NSString stringWithContentsOfFile:dictionaryFilePath
encoding:NSUTF8StringEncoding error:nil];
// Get array of string separated by new line
self.sharedListWords = [fileContents componentsSeparatedByCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
//self.sharedListWords = @[@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eight",@"nine",@"ten"];
self->sharedIndex = -1;
int numberOfThreads = 2;
// Run method working() in separate threads
for(int i=0; i<numberOfThreads; ++i)
{
//////////////////////////////////////////
// Create a thread
// Create new NSOperatin object with function puting in @selector() for run in other thread.
NSOperation* startBruteOper = [[NSInvocationOperation alloc]
initWithTarget:self selector:@selector(worker) object:nil];
// Add the operation to the queue and let it to be executed.
[operationQueue addOperation:startBruteOper];
[startBruteOper release];
/////////////////////////////////////////
}
}
- (void)worker
{
unsigned long countWords = [self.sharedListWords count];
int32_t index = 0;
// Use atomic operation for thread safe
while( (index = OSAtomicIncrement32( &(self->sharedIndex) ) ) < countWords )
{
NSLog(@"[%@] working on \"%@\"",
[NSThread currentThread],
[self.sharedListWords objectAtIndex:index]);
}
NSLog(@"[%@] work is finish.", [NSThread currentThread]);
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Multithreading queue list
operationQueue = [[NSOperationQueue alloc] init];
}
@end
#import "AppDelegate.h"
@implementation AppDelegate
- (IBAction)btnRun:(id)sender
{
// Read txt file dictionary of words, where is each words in new line.
NSString* dictionaryFilePath = [NSString stringWithFormat:@"/Users/admin/dictionary.txt"];
NSString* fileContents = [NSString stringWithContentsOfFile:dictionaryFilePath
encoding:NSUTF8StringEncoding error:nil];
// Get array of string separated by new line
self.sharedListWords = [fileContents componentsSeparatedByCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
//self.sharedListWords = @[@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eight",@"nine",@"ten"];
self->sharedIndex = -1;
int numberOfThreads = 2;
NSOperation* jobFinishedOper = [[NSInvocationOperation alloc]
initWithTarget:self selector:@selector(jobFinished) object:nil];
// Run method working() in separate threads
for(int i=0; i<numberOfThreads; ++i)
{
//////////////////////////////////////////
// Create a thread
// Create new NSOperatin object with function puting in @selector() for run in other thread.
NSOperation* startBruteOper = [[NSInvocationOperation alloc]
initWithTarget:self selector:@selector(worker) object:nil];
// Add the operation to the queue and let it to be executed.
[operationQueue addOperation:startBruteOper];
[jobFinishedOper addDependency:startBruteOper]; // 'jobFinishedOper' run only when 'startBruteOper' finished!
[startBruteOper release];
/////////////////////////////////////////
}
// 'jobFinishedOper' run only when all prevous operation is finished!
[operationQueue addOperation:jobFinishedOper];
[jobFinishedOper release];
}
- (void)worker
{
unsigned long countWords = [self.sharedListWords count];
int32_t index = 0;
// Use atomic operation for thread safe
while( (index = OSAtomicIncrement32( &(self->sharedIndex) ) ) < countWords )
{
NSLog(@"[%@] working on \"%@\"",
[NSThread currentThread],
[self.sharedListWords objectAtIndex:index]);
}
NSLog(@"[%@] work is finish.", [NSThread currentThread]);
}
- (void)jobFinished
{
self.sharedListWords = nil;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Multithreading queue list
operationQueue = [[NSOperationQueue alloc] init];
}
@end
#导入“AppDelegate.h”
@实现AppDelegate
-(iAction)btnRun:(id)发送方
{
//阅读txt文件字典中的单词,其中每一个单词都在新行中。
NSString*dictionaryFilePath=[NSString stringWithFormat:@”/Users/admin/dictionary.txt];
NSString*fileContents=[NSString stringWithContentsOfFile:dictionaryFilePath
编码:NSUTF8StringEncoding错误:nil];
//获取由新行分隔的字符串数组
self.sharedListWords=[fileContents组件由字符分隔集:
[NSCharacterSet newlineCharacterSet]];
//self.sharedListWords=@[“一”,“二”,“三”,“四”,“五”,“六”,“七”,“八”,“九”,“十];
self->sharedIndex=-1;
int numberOfThreads=2;
NSOperation*JobFinishedOpper=[[NSInvocationOperation alloc]
initWithTarget:自选择器:@selector(jobFinished)对象:nil];
//在单独的线程中运行方法working()
对于(int i=0;isharedIndex))
可能与Martin R>重复,我可以运行[self.sharedListWords release];在处理程序NSOperationQueue finish中?我正在测试几分钟)Martin R>我正在生成依赖处理程序jobFinished()看到更新的代码,第一次它工作正常,但当我按下第二次按钮时,它返回属性self.sharedListWords上的隔离错误。可能属性需要不同的释放?我太习惯于ARC了,以至于我几乎记不起MRC时间:-),但我认为您应该在jobFin中分配self.sharedListWords=nil
取消了
,而不是调用release
。