【发布时间】:2014-05-01 17:04:40
【问题描述】:
环境:Mac OS X 10.9、Xcode 5.0.2、ARC 已禁用。
问题:所有线程完成工作后如何释放属性内存。请参阅下面的示例。
我正在用一个按钮“(IBAction)btnRun:(id)sender”创建迷你示例。
示例读取 txt 文件并填充 NSArray 属性(sharedListWords)。然后运行两个线程,每个线程显示单词,
见OUT部分。当线程完成工作时,属性(self.sharedListWords)没有释放!但我想要为 (self.sharedListWords) 属性分配的空闲内存。动作“btnRun”在线程完成作业之前退出,我无法在此动作中释放(self.sharedListWords)。
线程完成工作后如何释放属性(self.sharedListWords)的内存?是的好答案here通过创建依赖操作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
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
OUT 部分:
[<NSThread: num = 2}] working on "one"
[<NSThread: num = 3}] working on "two"
[<NSThread: num = 2}] working on "three"
[<NSThread: num = 3}] working on "four"
[<NSThread: num = 2}] working on "five"
[<NSThread: num = 3}] working on "six"
[<NSThread: num = 2}] working on "seven"
[<NSThread: num = 3}] working on "eight"
[<NSThread: num = 2}] working on "nine"
[<NSThread: num = 3}] working on "ten"
[<NSThread: num = 2}] work is finish.
[<NSThread: num = 3}] work is finish.
【问题讨论】:
-
Martin R> 我可以运行 [self.sharedListWords release];在处理程序 NSOperationQueue 中完成?
-
我正在测试几分钟)
-
Martin R> 我正在让依赖处理程序 jobFinished() 查看更新的代码,第一次它工作正常,但是当我按下第二次按钮时,它在属性 self.sharedListWords 上返回分段错误。也许财产需要不同的释放?
-
我已经习惯了 ARC,以至于我几乎不记得 MRC 时间了 :-) 但我认为你应该在
jobFinished中分配self.sharedListWords = nil,而不是调用release。
标签: ios objective-c multithreading memory-management